Merge branch 'master' into layout_clear

pull/6547/head
Joshua Haberman 5 years ago
commit 78378dab22
  1. 2
      Makefile.am
  2. 7
      WORKSPACE
  3. 2
      conformance/failure_list_php_c.txt
  4. 9
      php/ext/google/protobuf/upb.c
  5. 38
      php/tests/encode_decode_test.php
  6. 6
      protobuf_deps.bzl
  7. 21
      ruby/ext/google/protobuf_c/defs.c
  8. 30
      ruby/ext/google/protobuf_c/encode_decode.c
  9. 20
      ruby/ext/google/protobuf_c/message.c
  10. 26
      ruby/ext/google/protobuf_c/protobuf.h
  11. 163
      ruby/ext/google/protobuf_c/storage.c
  12. 2
      src/google/protobuf/arena.h
  13. 2
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  14. 3
      src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
  15. 51
      src/google/protobuf/compiler/php/php_generator.cc
  16. 6
      third_party/six.BUILD

@ -1236,7 +1236,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
python/release/wheel/Dockerfile \ python/release/wheel/Dockerfile \
python/release/wheel/protobuf_optimized_pip.sh \ python/release/wheel/protobuf_optimized_pip.sh \
python/release/wheel/README.md \ python/release/wheel/README.md \
six.BUILD \ third_party/six.BUILD \
third_party/zlib.BUILD \ third_party/zlib.BUILD \
util/python/BUILD util/python/BUILD

@ -16,13 +16,6 @@ load("//:protobuf_deps.bzl", "protobuf_deps")
# Load common dependencies. # Load common dependencies.
protobuf_deps() protobuf_deps()
http_archive(
name = "six",
build_file = "@//:six.BUILD",
sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
urls = ["https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55"],
)
bind( bind(
name = "python_headers", name = "python_headers",
actual = "//util/python:python_headers", actual = "//util/python:python_headers",

@ -58,8 +58,6 @@ Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
Required.Proto3.JsonInput.FloatFieldNan.JsonOutput Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
Required.Proto3.JsonInput.OneofFieldDuplicate Required.Proto3.JsonInput.OneofFieldDuplicate
Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
Required.Proto3.JsonInput.RejectTopLevelNull Required.Proto3.JsonInput.RejectTopLevelNull
Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput

@ -9964,7 +9964,8 @@ static bool start_any_stringval(upb_json_parser *p) {
static bool start_stringval(upb_json_parser *p) { static bool start_stringval(upb_json_parser *p) {
if (is_top_level(p)) { if (is_top_level(p)) {
if (is_string_wrapper_object(p)) { if (is_string_wrapper_object(p) ||
is_number_wrapper_object(p)) {
start_wrapper_object(p); start_wrapper_object(p);
} else if (is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) { } else if (is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) {
start_fieldmask_object(p); start_fieldmask_object(p);
@ -9977,7 +9978,8 @@ static bool start_stringval(upb_json_parser *p) {
} else { } else {
return false; return false;
} }
} else if (does_string_wrapper_start(p)) { } else if (does_string_wrapper_start(p) ||
does_number_wrapper_start(p)) {
if (!start_subobject(p)) { if (!start_subobject(p)) {
return false; return false;
} }
@ -10183,7 +10185,8 @@ static bool end_stringval(upb_json_parser *p) {
return false; return false;
} }
if (does_string_wrapper_end(p)) { if (does_string_wrapper_end(p) ||
does_number_wrapper_end(p)) {
end_wrapper_object(p); end_wrapper_object(p);
if (!is_top_level(p)) { if (!is_top_level(p)) {
end_subobject(p); end_subobject(p);

@ -118,12 +118,19 @@ class EncodeDecodeTest extends TestBase
$this->assertEquals(1, $m->getValue()); $this->assertEquals(1, $m->getValue());
} }
# public function testEncodeTopLevelInt64Value() public function testDecodeTopLevelInt64ValueAsString()
# { {
# $m = new Int64Value(); $m = new Int64Value();
# $m->setValue(1); $m->mergeFromJsonString("\"1\"");
# $this->assertSame("\"1\"", $m->serializeToJsonString()); $this->assertEquals(1, $m->getValue());
# } }
public function testEncodeTopLevelInt64Value()
{
$m = new Int64Value();
$m->setValue(1);
$this->assertSame("\"1\"", $m->serializeToJsonString());
}
public function testDecodeTopLevelUInt64Value() public function testDecodeTopLevelUInt64Value()
{ {
@ -132,12 +139,19 @@ class EncodeDecodeTest extends TestBase
$this->assertEquals(1, $m->getValue()); $this->assertEquals(1, $m->getValue());
} }
# public function testEncodeTopLevelUInt64Value() public function testDecodeTopLevelUInt64ValueAsString()
# { {
# $m = new UInt64Value(); $m = new UInt64Value();
# $m->setValue(1); $m->mergeFromJsonString("\"1\"");
# $this->assertSame("\"1\"", $m->serializeToJsonString()); $this->assertEquals(1, $m->getValue());
# } }
public function testEncodeTopLevelUInt64Value()
{
$m = new UInt64Value();
$m->setValue(1);
$this->assertSame("\"1\"", $m->serializeToJsonString());
}
public function testDecodeTopLevelStringValue() public function testDecodeTopLevelStringValue()
{ {

@ -25,9 +25,9 @@ def protobuf_deps():
if not native.existing_rule("six"): if not native.existing_rule("six"):
http_archive( http_archive(
name = "six", name = "six",
build_file = "@//:six.BUILD", build_file = "@com_google_protobuf//:third_party/six.BUILD",
sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a", sha256 = "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73",
urls = ["https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55"], urls = ["https://pypi.python.org/packages/source/s/six/six-1.12.0.tar.gz"],
) )
if not native.existing_rule("rules_cc"): if not native.existing_rule("rules_cc"):

@ -2231,6 +2231,27 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
VALUE args[3] = { c_only_cookie, _descriptor_pool, key }; VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
def = rb_class_new_instance(3, args, klass); def = rb_class_new_instance(3, args, klass);
rb_hash_aset(descriptor_pool->def_to_descriptor, key, def); rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
// For message defs, we now eagerly get/create descriptors for all
// submessages. We will need these anyway to parse or serialize this
// message type. But more importantly, we must do this now so that
// add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
// need to create a Ruby object or insert into a Ruby Hash. We need to
// avoid triggering GC, which can switch Ruby threads and re-enter our
// C extension from a different thread. This wreaks havoc on our state
// if we were in the middle of building handlers.
if (klass == cDescriptor) {
const upb_msgdef *m = ptr;
upb_msg_field_iter it;
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)) {
get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
}
}
}
} }
return def; return def;

@ -155,6 +155,9 @@ static const void *newoneofhandlerdata(upb_handlers *h,
// create a separate ID space. In addition, using the field tag number here // create a separate ID space. In addition, using the field tag number here
// lets us easily look up the field in the oneof accessor. // lets us easily look up the field in the oneof accessor.
hd->oneof_case_num = upb_fielddef_number(f); hd->oneof_case_num = upb_fielddef_number(f);
if (is_value_field(f)) {
hd->oneof_case_num |= ONEOF_CASE_MASK;
}
hd->subklass = field_type_class(desc->layout, f); hd->subklass = field_type_class(desc->layout, f);
upb_handlers_addcleanup(h, hd, xfree); upb_handlers_addcleanup(h, hd, xfree);
return hd; return hd;
@ -706,12 +709,13 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) {
!upb_msg_field_done(&i); !upb_msg_field_done(&i);
upb_msg_field_next(&i)) { upb_msg_field_next(&i)) {
const upb_fielddef *f = upb_msg_iter_field(&i); const upb_fielddef *f = upb_msg_iter_field(&i);
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
sizeof(MessageHeader); sizeof(MessageHeader);
if (upb_fielddef_containingoneof(f)) { if (oneof) {
size_t oneof_case_offset = size_t oneof_case_offset =
desc->layout->fields[upb_fielddef_index(f)].case_offset + desc->layout->oneofs[upb_oneofdef_index(oneof)].case_offset +
sizeof(MessageHeader); sizeof(MessageHeader);
add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, desc); add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, desc);
} else if (is_map_field(f)) { } else if (is_map_field(f)) {
@ -1256,19 +1260,18 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
!upb_msg_field_done(&i); !upb_msg_field_done(&i);
upb_msg_field_next(&i)) { upb_msg_field_next(&i)) {
upb_fielddef *f = upb_msg_iter_field(&i); upb_fielddef *f = upb_msg_iter_field(&i);
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
bool is_matching_oneof = false; bool is_matching_oneof = false;
uint32_t offset = uint32_t offset =
desc->layout->fields[upb_fielddef_index(f)].offset + desc->layout->fields[upb_fielddef_index(f)].offset +
sizeof(MessageHeader); sizeof(MessageHeader);
if (upb_fielddef_containingoneof(f)) { if (oneof) {
uint32_t oneof_case_offset = uint32_t oneof_case =
desc->layout->fields[upb_fielddef_index(f)].case_offset + slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
sizeof(MessageHeader);
// For a oneof, check that this field is actually present -- skip all the // For a oneof, check that this field is actually present -- skip all the
// below if not. // below if not.
if (DEREF(msg, oneof_case_offset, uint32_t) != if (oneof_case != upb_fielddef_number(f)) {
upb_fielddef_number(f)) {
continue; continue;
} }
// Otherwise, fall through to the appropriate singular-field handler // Otherwise, fall through to the appropriate singular-field handler
@ -1464,18 +1467,17 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
upb_fielddef *f = upb_msg_iter_field(&it); upb_fielddef *f = upb_msg_iter_field(&it);
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
uint32_t offset = uint32_t offset =
desc->layout->fields[upb_fielddef_index(f)].offset + desc->layout->fields[upb_fielddef_index(f)].offset +
sizeof(MessageHeader); sizeof(MessageHeader);
if (upb_fielddef_containingoneof(f)) { if (oneof) {
uint32_t oneof_case_offset = uint32_t oneof_case =
desc->layout->fields[upb_fielddef_index(f)].case_offset + slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
sizeof(MessageHeader);
// For a oneof, check that this field is actually present -- skip all the // For a oneof, check that this field is actually present -- skip all the
// below if not. // below if not.
if (DEREF(msg, oneof_case_offset, uint32_t) != if (oneof_case != upb_fielddef_number(f)) {
upb_fielddef_number(f)) {
continue; continue;
} }
// Otherwise, fall through to the appropriate singular-field handler // Otherwise, fall through to the appropriate singular-field handler

@ -86,27 +86,11 @@ VALUE Message_alloc(VALUE klass) {
} }
static const upb_fielddef* which_oneof_field(MessageHeader* self, const upb_oneofdef* o) { static const upb_fielddef* which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
upb_oneof_iter it;
size_t case_ofs;
uint32_t oneof_case; uint32_t oneof_case;
const upb_fielddef* first_field;
const upb_fielddef* f; const upb_fielddef* f;
// If no fields in the oneof, always nil. oneof_case =
if (upb_oneofdef_numfields(o) == 0) { slot_read_oneof_case(self->descriptor->layout, Message_data(self), o);
return NULL;
}
// Grab the first field in the oneof so we can get its layout info to find the
// oneof_case field.
upb_oneof_begin(&it, o);
assert(!upb_oneof_done(&it));
first_field = upb_oneof_iter_field(&it);
assert(upb_fielddef_containingoneof(first_field) != NULL);
case_ofs =
self->descriptor->layout->
fields[upb_fielddef_index(first_field)].case_offset;
oneof_case = *((uint32_t*)((char*)Message_data(self) + case_ofs));
if (oneof_case == ONEOF_CASE_NONE) { if (oneof_case == ONEOF_CASE_NONE) {
return NULL; return NULL;

@ -59,6 +59,7 @@ typedef struct OneofDescriptor OneofDescriptor;
typedef struct EnumDescriptor EnumDescriptor; typedef struct EnumDescriptor EnumDescriptor;
typedef struct MessageLayout MessageLayout; typedef struct MessageLayout MessageLayout;
typedef struct MessageField MessageField; typedef struct MessageField MessageField;
typedef struct MessageOneof MessageOneof;
typedef struct MessageHeader MessageHeader; typedef struct MessageHeader MessageHeader;
typedef struct MessageBuilderContext MessageBuilderContext; typedef struct MessageBuilderContext MessageBuilderContext;
typedef struct OneofBuilderContext OneofBuilderContext; typedef struct OneofBuilderContext OneofBuilderContext;
@ -367,6 +368,9 @@ bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value); VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value);
void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value); void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value);
uint32_t slot_read_oneof_case(MessageLayout* layout, const void* storage,
const upb_oneofdef* oneof);
bool is_value_field(const upb_fielddef* f);
extern rb_encoding* kRubyStringUtf8Encoding; extern rb_encoding* kRubyStringUtf8Encoding;
extern rb_encoding* kRubyStringASCIIEncoding; extern rb_encoding* kRubyStringASCIIEncoding;
@ -496,13 +500,16 @@ VALUE Map_iter_value(Map_iter* iter);
// Message layout / storage. // Message layout / storage.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define MESSAGE_FIELD_NO_CASE ((size_t)-1) #define MESSAGE_FIELD_NO_HASBIT ((uint32_t)-1)
#define MESSAGE_FIELD_NO_HASBIT ((size_t)-1)
struct MessageField { struct MessageField {
size_t offset; uint32_t offset;
size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. uint32_t hasbit;
size_t hasbit; };
struct MessageOneof {
uint32_t offset;
uint32_t case_offset;
}; };
// MessageLayout is owned by the enclosing Descriptor, which must outlive us. // MessageLayout is owned by the enclosing Descriptor, which must outlive us.
@ -511,10 +518,15 @@ struct MessageLayout {
const upb_msgdef* msgdef; const upb_msgdef* msgdef;
void* empty_template; // Can memcpy() onto a layout to clear it. void* empty_template; // Can memcpy() onto a layout to clear it.
MessageField* fields; MessageField* fields;
size_t size; MessageOneof* oneofs;
uint32_t size;
uint32_t value_offset;
int value_count;
}; };
void create_layout(Descriptor* desc); #define ONEOF_CASE_MASK 0x80000000
MessageLayout* create_layout(Descriptor* desc);
void free_layout(MessageLayout* layout); void free_layout(MessageLayout* layout);
bool field_contains_hasbit(MessageLayout* layout, bool field_contains_hasbit(MessageLayout* layout,
const upb_fielddef* field); const upb_fielddef* field);

@ -473,10 +473,16 @@ static size_t align_up_to(size_t offset, size_t granularity) {
return (offset + granularity - 1) & ~(granularity - 1); return (offset + granularity - 1) & ~(granularity - 1);
} }
void create_layout(Descriptor* desc) { bool is_value_field(const upb_fielddef* f) {
return upb_fielddef_isseq(f) || upb_fielddef_issubmsg(f) ||
upb_fielddef_isstring(f);
}
MessageLayout* create_layout(Descriptor* desc) {
const upb_msgdef *msgdef = desc->msgdef; const upb_msgdef *msgdef = desc->msgdef;
MessageLayout* layout = ALLOC(MessageLayout); MessageLayout* layout = ALLOC(MessageLayout);
int nfields = upb_msgdef_numfields(msgdef); int nfields = upb_msgdef_numfields(msgdef);
int noneofs = upb_msgdef_numoneofs(msgdef);
upb_msg_field_iter it; upb_msg_field_iter it;
upb_msg_oneof_iter oit; upb_msg_oneof_iter oit;
size_t off = 0; size_t off = 0;
@ -487,6 +493,11 @@ void create_layout(Descriptor* desc) {
desc->layout = layout; desc->layout = layout;
layout->fields = ALLOC_N(MessageField, nfields); layout->fields = ALLOC_N(MessageField, nfields);
layout->oneofs = NULL;
if (noneofs > 0) {
layout->oneofs = ALLOC_N(MessageOneof, noneofs);
}
for (upb_msg_field_begin(&it, msgdef); for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
@ -504,29 +515,41 @@ void create_layout(Descriptor* desc) {
off += (hasbit + 8 - 1) / 8; off += (hasbit + 8 - 1) / 8;
} }
off = align_up_to(off, sizeof(VALUE));
layout->value_offset = off;
layout->value_count = 0;
// Place all (non-oneof) VALUE fields first.
for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it);
if (upb_fielddef_containingoneof(field) || !is_value_field(field)) {
continue;
}
layout->fields[upb_fielddef_index(field)].offset = off;
off += sizeof(VALUE);
layout->value_count++;
}
// Now place all other (non-oneof) fields.
for (upb_msg_field_begin(&it, msgdef); for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it); const upb_fielddef* field = upb_msg_iter_field(&it);
size_t field_size; size_t field_size;
if (upb_fielddef_containingoneof(field)) { if (upb_fielddef_containingoneof(field) || is_value_field(field)) {
// Oneofs are handled separately below.
continue; continue;
} }
// Allocate |field_size| bytes for this field in the layout. // Allocate |field_size| bytes for this field in the layout.
field_size = 0; field_size = native_slot_size(upb_fielddef_type(field));
if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
field_size = sizeof(VALUE);
} else {
field_size = native_slot_size(upb_fielddef_type(field));
}
// Align current offset up to |size| granularity. // Align current offset up to |size| granularity.
off = align_up_to(off, field_size); off = align_up_to(off, field_size);
layout->fields[upb_fielddef_index(field)].offset = off; layout->fields[upb_fielddef_index(field)].offset = off;
layout->fields[upb_fielddef_index(field)].case_offset =
MESSAGE_FIELD_NO_CASE;
off += field_size; off += field_size;
} }
@ -560,6 +583,7 @@ void create_layout(Descriptor* desc) {
upb_oneof_next(&fit)) { upb_oneof_next(&fit)) {
const upb_fielddef* field = upb_oneof_iter_field(&fit); const upb_fielddef* field = upb_oneof_iter_field(&fit);
layout->fields[upb_fielddef_index(field)].offset = off; layout->fields[upb_fielddef_index(field)].offset = off;
layout->oneofs[upb_oneofdef_index(oneof)].offset = off;
} }
off += field_size; off += field_size;
} }
@ -569,18 +593,10 @@ void create_layout(Descriptor* desc) {
!upb_msg_oneof_done(&oit); !upb_msg_oneof_done(&oit);
upb_msg_oneof_next(&oit)) { upb_msg_oneof_next(&oit)) {
const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit); const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
upb_oneof_iter fit;
size_t field_size = sizeof(uint32_t); size_t field_size = sizeof(uint32_t);
// Align the offset. // Align the offset.
off = (off + field_size - 1) & ~(field_size - 1); off = (off + field_size - 1) & ~(field_size - 1);
// Assign all fields in the oneof this same offset. layout->oneofs[upb_oneofdef_index(oneof)].case_offset = off;
for (upb_oneof_begin(&fit, oneof);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* field = upb_oneof_iter_field(&fit);
layout->fields[upb_fielddef_index(field)].case_offset = off;
}
off += field_size; off += field_size;
} }
@ -601,6 +617,7 @@ void create_layout(Descriptor* desc) {
void free_layout(MessageLayout* layout) { void free_layout(MessageLayout* layout) {
xfree(layout->empty_template); xfree(layout->empty_template);
xfree(layout->fields); xfree(layout->fields);
xfree(layout->oneofs);
xfree(layout); xfree(layout);
} }
@ -627,9 +644,15 @@ static void* slot_memory(MessageLayout* layout,
static uint32_t* slot_oneof_case(MessageLayout* layout, static uint32_t* slot_oneof_case(MessageLayout* layout,
const void* storage, const void* storage,
const upb_fielddef* field) { const upb_oneofdef* oneof) {
return (uint32_t *)(((uint8_t *)storage) + return (uint32_t*)(((uint8_t*)storage) +
layout->fields[upb_fielddef_index(field)].case_offset); layout->oneofs[upb_oneofdef_index(oneof)].case_offset);
}
uint32_t slot_read_oneof_case(MessageLayout* layout, const void* storage,
const upb_oneofdef* oneof) {
uint32_t* ptr = slot_oneof_case(layout, storage, oneof);
return *ptr & ~ONEOF_CASE_MASK;
} }
static void slot_set_hasbit(MessageLayout* layout, static void slot_set_hasbit(MessageLayout* layout,
@ -672,13 +695,14 @@ void layout_clear(MessageLayout* layout,
const void* storage, const void* storage,
const upb_fielddef* field) { const upb_fielddef* field) {
void* memory = slot_memory(layout, storage, field); void* memory = slot_memory(layout, storage, field);
uint32_t* oneof_case = slot_oneof_case(layout, storage, field); const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
if (field_contains_hasbit(layout, field)) { if (field_contains_hasbit(layout, field)) {
slot_clear_hasbit(layout, storage, field); slot_clear_hasbit(layout, storage, field);
} }
if (upb_fielddef_containingoneof(field)) { if (oneof) {
uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
memset(memory, 0, NATIVE_SLOT_MAX_SIZE); memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
*oneof_case = ONEOF_CASE_NONE; *oneof_case = ONEOF_CASE_NONE;
} else if (is_map_field(field)) { } else if (is_map_field(field)) {
@ -764,8 +788,7 @@ VALUE layout_get(MessageLayout* layout,
const void* storage, const void* storage,
const upb_fielddef* field) { const upb_fielddef* field) {
void* memory = slot_memory(layout, storage, field); void* memory = slot_memory(layout, storage, field);
uint32_t* oneof_case = slot_oneof_case(layout, storage, field); const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
bool field_set; bool field_set;
if (field_contains_hasbit(layout, field)) { if (field_contains_hasbit(layout, field)) {
field_set = slot_is_hasbit_set(layout, storage, field); field_set = slot_is_hasbit_set(layout, storage, field);
@ -773,8 +796,9 @@ VALUE layout_get(MessageLayout* layout,
field_set = true; field_set = true;
} }
if (upb_fielddef_containingoneof(field)) { if (oneof) {
if (*oneof_case != upb_fielddef_number(field)) { uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof);
if (oneof_case != upb_fielddef_number(field)) {
return layout_get_default(field); return layout_get_default(field);
} }
return native_slot_get(upb_fielddef_type(field), return native_slot_get(upb_fielddef_type(field),
@ -837,9 +861,10 @@ void layout_set(MessageLayout* layout,
const upb_fielddef* field, const upb_fielddef* field,
VALUE val) { VALUE val) {
void* memory = slot_memory(layout, storage, field); void* memory = slot_memory(layout, storage, field);
uint32_t* oneof_case = slot_oneof_case(layout, storage, field); const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
if (upb_fielddef_containingoneof(field)) { if (oneof) {
uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
if (val == Qnil) { if (val == Qnil) {
// Assigning nil to a oneof field clears the oneof completely. // Assigning nil to a oneof field clears the oneof completely.
*oneof_case = ONEOF_CASE_NONE; *oneof_case = ONEOF_CASE_NONE;
@ -857,11 +882,14 @@ void layout_set(MessageLayout* layout,
// sync with the value slot whenever the Ruby VM has been called. Thus, we // sync with the value slot whenever the Ruby VM has been called. Thus, we
// use native_slot_set_value_and_case(), which ensures that both the value // use native_slot_set_value_and_case(), which ensures that both the value
// and case number are altered atomically (w.r.t. the Ruby VM). // and case number are altered atomically (w.r.t. the Ruby VM).
uint32_t case_value = upb_fielddef_number(field);
if (upb_fielddef_issubmsg(field) || upb_fielddef_isstring(field)) {
case_value |= ONEOF_CASE_MASK;
}
native_slot_set_value_and_case( native_slot_set_value_and_case(
upb_fielddef_name(field), upb_fielddef_name(field), upb_fielddef_type(field),
upb_fielddef_type(field), field_type_class(layout, field), field_type_class(layout, field), memory, val, oneof_case, case_value);
memory, val,
oneof_case, upb_fielddef_number(field));
} }
} else if (is_map_field(field)) { } else if (is_map_field(field)) {
check_map_field_type(layout, val, field); check_map_field_type(layout, val, field);
@ -893,22 +921,19 @@ void layout_init(MessageLayout* layout, void* storage) {
} }
void layout_mark(MessageLayout* layout, void* storage) { void layout_mark(MessageLayout* layout, void* storage) {
upb_msg_field_iter it; VALUE* values = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
for (upb_msg_field_begin(&it, layout->msgdef); int noneofs = upb_msgdef_numoneofs(layout->msgdef);
!upb_msg_field_done(&it); int i;
upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it);
void* memory = slot_memory(layout, storage, field);
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
if (upb_fielddef_containingoneof(field)) { for (i = 0; i < layout->value_count; i++) {
if (*oneof_case == upb_fielddef_number(field)) { rb_gc_mark(values[i]);
native_slot_mark(upb_fielddef_type(field), memory); }
}
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { for (i = 0; i < noneofs; i++) {
rb_gc_mark(DEREF(memory, VALUE)); MessageOneof* oneof = &layout->oneofs[i];
} else { uint32_t* case_ptr = (uint32_t*)CHARPTR_AT(storage, oneof->case_offset);
native_slot_mark(upb_fielddef_type(field), memory); if (*case_ptr & ONEOF_CASE_MASK) {
rb_gc_mark(DEREF_OFFSET(storage, oneof->offset, VALUE));
} }
} }
} }
@ -919,14 +944,16 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it); const upb_fielddef* field = upb_msg_iter_field(&it);
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
void* to_memory = slot_memory(layout, to, field); void* to_memory = slot_memory(layout, to, field);
uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
void* from_memory = slot_memory(layout, from, field); void* from_memory = slot_memory(layout, from, field);
uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
if (upb_fielddef_containingoneof(field)) { if (oneof) {
if (*from_oneof_case == upb_fielddef_number(field)) { uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
if (slot_read_oneof_case(layout, from, oneof) ==
upb_fielddef_number(field)) {
*to_oneof_case = *from_oneof_case; *to_oneof_case = *from_oneof_case;
native_slot_dup(upb_fielddef_type(field), to_memory, from_memory); native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
} }
@ -951,14 +978,16 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it); const upb_fielddef* field = upb_msg_iter_field(&it);
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
void* to_memory = slot_memory(layout, to, field); void* to_memory = slot_memory(layout, to, field);
uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
void* from_memory = slot_memory(layout, from, field); void* from_memory = slot_memory(layout, from, field);
uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
if (upb_fielddef_containingoneof(field)) { if (oneof) {
if (*from_oneof_case == upb_fielddef_number(field)) { uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
if (slot_read_oneof_case(layout, from, oneof) ==
upb_fielddef_number(field)) {
*to_oneof_case = *from_oneof_case; *to_oneof_case = *from_oneof_case;
native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory); native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
} }
@ -985,17 +1014,18 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it); const upb_fielddef* field = upb_msg_iter_field(&it);
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
void* msg1_memory = slot_memory(layout, msg1, field); void* msg1_memory = slot_memory(layout, msg1, field);
uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, field);
void* msg2_memory = slot_memory(layout, msg2, field); void* msg2_memory = slot_memory(layout, msg2, field);
uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, field);
if (upb_fielddef_containingoneof(field)) { if (oneof) {
uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, oneof);
uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, oneof);
if (*msg1_oneof_case != *msg2_oneof_case || if (*msg1_oneof_case != *msg2_oneof_case ||
(*msg1_oneof_case == upb_fielddef_number(field) && (slot_read_oneof_case(layout, msg1, oneof) ==
!native_slot_eq(upb_fielddef_type(field), upb_fielddef_number(field) &&
msg1_memory, !native_slot_eq(upb_fielddef_type(field), msg1_memory,
msg2_memory))) { msg2_memory))) {
return Qfalse; return Qfalse;
} }
@ -1011,9 +1041,8 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
} }
} else { } else {
if (slot_is_hasbit_set(layout, msg1, field) != if (slot_is_hasbit_set(layout, msg1, field) !=
slot_is_hasbit_set(layout, msg2, field) || slot_is_hasbit_set(layout, msg2, field) ||
!native_slot_eq(upb_fielddef_type(field), !native_slot_eq(upb_fielddef_type(field), msg1_memory, msg2_memory)) {
msg1_memory, msg2_memory)) {
return Qfalse; return Qfalse;
} }
} }

@ -75,6 +75,8 @@ namespace protobuf {
class Arena; // defined below class Arena; // defined below
class Message; // defined in message.h class Message; // defined in message.h
class MessageLite; class MessageLite;
template <typename Key, typename T>
class Map;
namespace arena_metrics { namespace arena_metrics {

@ -297,7 +297,7 @@ uint GetGroupEndTag(const Descriptor* descriptor) {
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
std::string result = GetFileNamespace(file); std::string result = GetFileNamespace(file);
if (result != "") { if (!result.empty()) {
result += '.'; result += '.';
} }
string classname; string classname;

@ -261,6 +261,7 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript
// Fields // Fields
if (descriptor->field_count() > 0) { if (descriptor->field_count() > 0) {
std::vector<std::string> fields; std::vector<std::string> fields;
fields.reserve(descriptor->field_count());
for (int i = 0; i < descriptor->field_count(); i++) { for (int i = 0; i < descriptor->field_count(); i++) {
fields.push_back(GetPropertyName(descriptor->field(i))); fields.push_back(GetPropertyName(descriptor->field(i)));
} }
@ -273,6 +274,7 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript
// Oneofs // Oneofs
if (descriptor->oneof_decl_count() > 0) { if (descriptor->oneof_decl_count() > 0) {
std::vector<std::string> oneofs; std::vector<std::string> oneofs;
oneofs.reserve(descriptor->oneof_decl_count());
for (int i = 0; i < descriptor->oneof_decl_count(); i++) { for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true)); oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
} }
@ -285,6 +287,7 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript
// Nested enums // Nested enums
if (descriptor->enum_type_count() > 0) { if (descriptor->enum_type_count() > 0) {
std::vector<std::string> enums; std::vector<std::string> enums;
enums.reserve(descriptor->enum_type_count());
for (int i = 0; i < descriptor->enum_type_count(); i++) { for (int i = 0; i < descriptor->enum_type_count(); i++) {
enums.push_back(GetClassName(descriptor->enum_type(i))); enums.push_back(GetClassName(descriptor->enum_type(i)));
} }

@ -88,7 +88,6 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
std::string LabelForField(FieldDescriptor* field); std::string LabelForField(FieldDescriptor* field);
std::string TypeName(FieldDescriptor* field); std::string TypeName(FieldDescriptor* field);
std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter); std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
std::string EscapeDollor(const string& to_escape);
std::string BinaryToHex(const string& binary); std::string BinaryToHex(const string& binary);
void Indent(io::Printer* printer); void Indent(io::Printer* printer);
void Outdent(io::Printer* printer); void Outdent(io::Printer* printer);
@ -153,7 +152,7 @@ template <typename DescriptorType>
std::string ClassNamePrefix(const string& classname, std::string ClassNamePrefix(const string& classname,
const DescriptorType* desc) { const DescriptorType* desc) {
const string& prefix = (desc->file()->options()).php_class_prefix(); const string& prefix = (desc->file()->options()).php_class_prefix();
if (prefix != "") { if (!prefix.empty()) {
return prefix; return prefix;
} }
@ -244,13 +243,13 @@ template <typename DescriptorType>
std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) {
if (desc->file()->options().has_php_namespace()) { if (desc->file()->options().has_php_namespace()) {
const string& php_namespace = desc->file()->options().php_namespace(); const string& php_namespace = desc->file()->options().php_namespace();
if (php_namespace != "") { if (!php_namespace.empty()) {
return php_namespace; return php_namespace;
} }
return ""; return "";
} }
if (desc->file()->package() != "") { if (!desc->file()->package().empty()) {
return PhpName(desc->file()->package(), is_descriptor); return PhpName(desc->file()->package(), is_descriptor);
} }
return ""; return "";
@ -260,7 +259,7 @@ template <typename DescriptorType>
std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
string classname = GeneratedClassNameImpl(desc); string classname = GeneratedClassNameImpl(desc);
string php_namespace = RootPhpNamespace(desc, is_descriptor); string php_namespace = RootPhpNamespace(desc, is_descriptor);
if (php_namespace != "") { if (!php_namespace.empty()) {
return php_namespace + "\\" + classname; return php_namespace + "\\" + classname;
} }
return classname; return classname;
@ -270,7 +269,7 @@ template <typename DescriptorType>
std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) { std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) {
string classname = LegacyGeneratedClassName(desc); string classname = LegacyGeneratedClassName(desc);
string php_namespace = RootPhpNamespace(desc, is_descriptor); string php_namespace = RootPhpNamespace(desc, is_descriptor);
if (php_namespace != "") { if (!php_namespace.empty()) {
return php_namespace + "\\" + classname; return php_namespace + "\\" + classname;
} }
return classname; return classname;
@ -352,7 +351,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
if (file->options().has_php_metadata_namespace()) { if (file->options().has_php_metadata_namespace()) {
const string& php_metadata_namespace = const string& php_metadata_namespace =
file->options().php_metadata_namespace(); file->options().php_metadata_namespace();
if (php_metadata_namespace != "" && php_metadata_namespace != "\\") { if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") {
result += php_metadata_namespace; result += php_metadata_namespace;
std::replace(result.begin(), result.end(), '\\', '/'); std::replace(result.begin(), result.end(), '\\', '/');
if (result.at(result.size() - 1) != '/') { if (result.at(result.size() - 1) != '/') {
@ -552,45 +551,41 @@ std::string EnumOrMessageSuffix(
// Converts a name to camel-case. If cap_first_letter is true, capitalize the // Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter. // first letter.
std::string UnderscoresToCamelCase(const string& input, bool cap_first_letter) { std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) {
std::string result; std::string result;
for (int i = 0; i < input.size(); i++) { for (int i = 0; i < name.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') { if ('a' <= name[i] && name[i] <= 'z') {
if (cap_first_letter) { if (cap_first_letter) {
result += input[i] + ('A' - 'a'); result += name[i] + ('A' - 'a');
} else { } else {
result += input[i]; result += name[i];
} }
cap_first_letter = false; cap_first_letter = false;
} else if ('A' <= input[i] && input[i] <= 'Z') { } else if ('A' <= name[i] && name[i] <= 'Z') {
if (i == 0 && !cap_first_letter) { if (i == 0 && !cap_first_letter) {
// Force first letter to lower-case unless explicitly told to // Force first letter to lower-case unless explicitly told to
// capitalize it. // capitalize it.
result += input[i] + ('a' - 'A'); result += name[i] + ('a' - 'A');
} else { } else {
// Capital letters after the first are left as-is. // Capital letters after the first are left as-is.
result += input[i]; result += name[i];
} }
cap_first_letter = false; cap_first_letter = false;
} else if ('0' <= input[i] && input[i] <= '9') { } else if ('0' <= name[i] && name[i] <= '9') {
result += input[i]; result += name[i];
cap_first_letter = true; cap_first_letter = true;
} else { } else {
cap_first_letter = true; cap_first_letter = true;
} }
} }
// Add a trailing "_" if the name should be altered. // Add a trailing "_" if the name should be altered.
if (input[input.size() - 1] == '#') { if (name[name.size() - 1] == '#') {
result += '_'; result += '_';
} }
return result; return result;
} }
std::string EscapeDollor(const string& to_escape) { std::string BinaryToHex(const string& binary) {
return StringReplace(to_escape, "$", "\\$", true);
}
std::string BinaryToHex(const string& src) {
string dest; string dest;
size_t i; size_t i;
unsigned char symbol[16] = { unsigned char symbol[16] = {
@ -600,12 +595,12 @@ std::string BinaryToHex(const string& src) {
'c', 'd', 'e', 'f', 'c', 'd', 'e', 'f',
}; };
dest.resize(src.size() * 2); dest.resize(binary.size() * 2);
char* append_ptr = &dest[0]; char* append_ptr = &dest[0];
for (i = 0; i < src.size(); i++) { for (i = 0; i < binary.size(); i++) {
*append_ptr++ = symbol[(src[i] & 0xf0) >> 4]; *append_ptr++ = symbol[(binary[i] & 0xf0) >> 4];
*append_ptr++ = symbol[src[i] & 0x0f]; *append_ptr++ = symbol[binary[i] & 0x0f];
} }
return dest; return dest;
@ -1103,7 +1098,7 @@ void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* d
GenerateHead(file, &printer); GenerateHead(file, &printer);
std::string php_namespace = RootPhpNamespace(desc, is_descriptor); std::string php_namespace = RootPhpNamespace(desc, is_descriptor);
if (php_namespace != "") { if (!php_namespace.empty()) {
printer.Print( printer.Print(
"namespace ^name^;\n\n", "namespace ^name^;\n\n",
"name", php_namespace); "name", php_namespace);

@ -1,13 +1,13 @@
genrule( genrule(
name = "copy_six", name = "copy_six",
srcs = ["six-1.10.0/six.py"], srcs = ["six-1.12.0/six.py"],
outs = ["six.py"], outs = ["__init__.py"],
cmd = "cp $< $(@)", cmd = "cp $< $(@)",
) )
py_library( py_library(
name = "six", name = "six",
srcs = ["six.py"], srcs = ["__init__.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
Loading…
Cancel
Save