Merge pull request #5430 from acozzette/fixes-for-3.7

Cherry-picked some internal fixes from Google
pull/5436/head
Adam Cozzette 6 years ago committed by GitHub
commit 93d5efaa4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      python/google/protobuf/pyext/map_container.cc
  2. 10
      src/google/protobuf/generated_message_reflection.cc
  3. 7
      src/google/protobuf/generated_message_reflection.h
  4. 2
      src/google/protobuf/map_field.h
  5. 13
      src/google/protobuf/map_test.cc
  6. 7
      src/google/protobuf/message.h
  7. 26
      src/google/protobuf/reflection_ops.cc
  8. 2
      src/google/protobuf/text_format.cc
  9. 8
      src/google/protobuf/wire_format.cc

@ -346,11 +346,11 @@ PyObject* MapReflectionFriend::MergeFrom(PyObject* _self, PyObject* arg) {
const Message* other_message = other_map->message; const Message* other_message = other_map->message;
const Reflection* reflection = message->GetReflection(); const Reflection* reflection = message->GetReflection();
const Reflection* other_reflection = other_message->GetReflection(); const Reflection* other_reflection = other_message->GetReflection();
internal::MapFieldBase* field = reflection->MapData( internal::MapFieldBase* field = reflection->MutableMapData(
message, self->parent_field_descriptor); message, self->parent_field_descriptor);
internal::MapFieldBase* other_field = const internal::MapFieldBase* other_field =
other_reflection->MapData(const_cast<Message*>(other_message), other_reflection->GetMapData(*other_message,
self->parent_field_descriptor); self->parent_field_descriptor);
field->MergeFrom(*other_field); field->MergeFrom(*other_field);
self->version++; self->version++;
Py_RETURN_NONE; Py_RETURN_NONE;

@ -2224,7 +2224,7 @@ void* GeneratedMessageReflection::RepeatedFieldData(
} }
} }
MapFieldBase* GeneratedMessageReflection::MapData( MapFieldBase* GeneratedMessageReflection::MutableMapData(
Message* message, const FieldDescriptor* field) const { Message* message, const FieldDescriptor* field) const {
USAGE_CHECK(IsMapFieldInApi(field), USAGE_CHECK(IsMapFieldInApi(field),
"GetMapData", "GetMapData",
@ -2232,6 +2232,14 @@ MapFieldBase* GeneratedMessageReflection::MapData(
return MutableRaw<MapFieldBase>(message, field); return MutableRaw<MapFieldBase>(message, field);
} }
const MapFieldBase* GeneratedMessageReflection::GetMapData(
const Message& message, const FieldDescriptor* field) const {
USAGE_CHECK(IsMapFieldInApi(field),
"GetMapData",
"Field is not a map field.");
return &(GetRaw<MapFieldBase>(message, field));
}
namespace { namespace {
// Helper function to transform migration schema into reflection schema. // Helper function to transform migration schema into reflection schema.

@ -670,8 +670,11 @@ class GeneratedMessageReflection final : public Reflection {
Message* sub_message, Message* sub_message,
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
internal::MapFieldBase* MapData(Message* message, internal::MapFieldBase* MutableMapData(
const FieldDescriptor* field) const override; Message* message, const FieldDescriptor* field) const override;
const internal::MapFieldBase* GetMapData(
const Message& message, const FieldDescriptor* field) const override;
friend inline // inline so nobody can call this function. friend inline // inline so nobody can call this function.
void void

@ -742,7 +742,7 @@ class PROTOBUF_EXPORT MapIterator {
public: public:
MapIterator(Message* message, const FieldDescriptor* field) { MapIterator(Message* message, const FieldDescriptor* field) {
const Reflection* reflection = message->GetReflection(); const Reflection* reflection = message->GetReflection();
map_ = reflection->MapData(message, field); map_ = reflection->MutableMapData(message, field);
key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type()); key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type()); value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
map_->InitializeIterator(this); map_->InitializeIterator(this);

@ -2042,19 +2042,30 @@ TEST(GeneratedMapFieldTest, DynamicMessageMergeFromDynamicMessage) {
unittest::TestMap::descriptor()); unittest::TestMap::descriptor());
reflection_tester.SetMapFieldsViaMapReflection(message1.get()); reflection_tester.SetMapFieldsViaMapReflection(message1.get());
// message2 is created by same factory.
std::unique_ptr<Message> message2; std::unique_ptr<Message> message2;
message2.reset( message2.reset(
factory.GetPrototype(unittest::TestMap::descriptor())->New()); factory.GetPrototype(unittest::TestMap::descriptor())->New());
reflection_tester.SetMapFieldsViaMapReflection(message2.get()); reflection_tester.SetMapFieldsViaMapReflection(message2.get());
// message3 is created by different factory.
DynamicMessageFactory factory3;
std::unique_ptr<Message> message3;
message3.reset(
factory3.GetPrototype(unittest::TestMap::descriptor())->New());
reflection_tester.SetMapFieldsViaMapReflection(message3.get());
message2->MergeFrom(*message1); message2->MergeFrom(*message1);
message3->MergeFrom(*message1);
// Test MergeFrom does not sync to repeated fields and // Test MergeFrom does not sync to repeated fields and
// there is no duplicate keys in text format. // there is no duplicate keys in text format.
string output1, output2; string output1, output2, output3;
TextFormat::PrintToString(*message1, &output1); TextFormat::PrintToString(*message1, &output1);
TextFormat::PrintToString(*message2, &output2); TextFormat::PrintToString(*message2, &output2);
TextFormat::PrintToString(*message3, &output3);
EXPECT_EQ(output1, output2); EXPECT_EQ(output1, output2);
EXPECT_EQ(output1, output3);
} }
TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) { TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) {

@ -1049,11 +1049,16 @@ class PROTOBUF_EXPORT Reflection {
// Help method for MapIterator. // Help method for MapIterator.
friend class MapIterator; friend class MapIterator;
virtual internal::MapFieldBase* MapData( virtual internal::MapFieldBase* MutableMapData(
Message* /* message */, const FieldDescriptor* /* field */) const { Message* /* message */, const FieldDescriptor* /* field */) const {
return NULL; return NULL;
} }
virtual const internal::MapFieldBase* GetMapData(
const Message& /* message */, const FieldDescriptor* /* field */) const {
return NULL;
}
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
}; };

@ -77,6 +77,10 @@ void ReflectionOps::Merge(const Message& from, Message* to) {
const Reflection* from_reflection = GetReflectionOrDie(from); const Reflection* from_reflection = GetReflectionOrDie(from);
const Reflection* to_reflection = GetReflectionOrDie(*to); const Reflection* to_reflection = GetReflectionOrDie(*to);
bool is_from_generated = (from_reflection->GetMessageFactory() ==
google::protobuf::MessageFactory::generated_factory());
bool is_to_generated = (to_reflection->GetMessageFactory() ==
google::protobuf::MessageFactory::generated_factory());
std::vector<const FieldDescriptor*> fields; std::vector<const FieldDescriptor*> fields;
from_reflection->ListFields(from, &fields); from_reflection->ListFields(from, &fields);
@ -84,15 +88,17 @@ void ReflectionOps::Merge(const Message& from, Message* to) {
const FieldDescriptor* field = fields[i]; const FieldDescriptor* field = fields[i];
if (field->is_repeated()) { if (field->is_repeated()) {
if (field->is_map()) { // Use map reflection if both are in map status and have the
MapFieldBase* from_field = // same map type to avoid sync with repeated field.
from_reflection->MapData(const_cast<Message*>(&from), field); // Note: As from and to messages have the same descriptor, the
// map field types are the same if they are both generated
// messages or both dynamic messages.
if (is_from_generated == is_to_generated && field->is_map()) {
const MapFieldBase* from_field =
from_reflection->GetMapData(from, field);
MapFieldBase* to_field = MapFieldBase* to_field =
to_reflection->MapData(const_cast<Message*>(to), field); to_reflection->MutableMapData(to, field);
// Use map reflection if both are in map status and have the if (to_field->IsMapValid() && from_field->IsMapValid()) {
// same map type to avoid sync with repeated field.
if (to_field->IsMapValid() && from_field->IsMapValid()
&& typeid(*from_field) == typeid(*to_field)) {
to_field->MergeFrom(*from_field); to_field->MergeFrom(*from_field);
continue; continue;
} }
@ -189,8 +195,8 @@ bool ReflectionOps::IsInitialized(const Message& message) {
if (field->is_map()) { if (field->is_map()) {
const FieldDescriptor* value_field = field->message_type()->field(1); const FieldDescriptor* value_field = field->message_type()->field(1);
if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
MapFieldBase* map_field = const MapFieldBase* map_field =
reflection->MapData(const_cast<Message*>(&message), field); reflection->GetMapData(message, field);
if (map_field->IsMapValid()) { if (map_field->IsMapValid()) {
MapIterator iter(const_cast<Message*>(&message), field); MapIterator iter(const_cast<Message*>(&message), field);
MapIterator end(const_cast<Message*>(&message), field); MapIterator end(const_cast<Message*>(&message), field);

@ -2049,7 +2049,7 @@ bool MapFieldPrinterHelper::SortMap(
std::vector<const Message*>* sorted_map_field) { std::vector<const Message*>* sorted_map_field) {
bool need_release = false; bool need_release = false;
const MapFieldBase& base = const MapFieldBase& base =
*reflection->MapData(const_cast<Message*>(&message), field); *reflection->GetMapData(message, field);
if (base.IsRepeatedFieldValid()) { if (base.IsRepeatedFieldValid()) {
const RepeatedPtrField<Message>& map_field = const RepeatedPtrField<Message>& map_field =

@ -907,8 +907,8 @@ void WireFormat::SerializeFieldWithCachedSizes(
// internal state and existing references that came from map reflection remain // internal state and existing references that came from map reflection remain
// valid for both reading and writing. // valid for both reading and writing.
if (field->is_map()) { if (field->is_map()) {
MapFieldBase* map_field = const MapFieldBase* map_field =
message_reflection->MapData(const_cast<Message*>(&message), field); message_reflection->GetMapData(message, field);
if (map_field->IsMapValid()) { if (map_field->IsMapValid()) {
if (output->IsSerializationDeterministic()) { if (output->IsSerializationDeterministic()) {
std::vector<MapKey> sorted_key_list = std::vector<MapKey> sorted_key_list =
@ -1243,8 +1243,8 @@ size_t WireFormat::FieldDataOnlyByteSize(
size_t data_size = 0; size_t data_size = 0;
if (field->is_map()) { if (field->is_map()) {
MapFieldBase* map_field = const MapFieldBase* map_field =
message_reflection->MapData(const_cast<Message*>(&message), field); message_reflection->GetMapData(message, field);
if (map_field->IsMapValid()) { if (map_field->IsMapValid()) {
MapIterator iter(const_cast<Message*>(&message), field); MapIterator iter(const_cast<Message*>(&message), field);
MapIterator end(const_cast<Message*>(&message), field); MapIterator end(const_cast<Message*>(&message), field);

Loading…
Cancel
Save