Reduce stack usage of MessageDifferencer recursion by almost half:

- Stop using FixedArray. Memory allocators have improved since then, so the wins are smaller.
 - Prevent allocating SpecificField object in the stack. It is 96 bytes and stays in the stack frame even if used temporarily in the function.

PiperOrigin-RevId: 534454119
pull/12877/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent f215e21f8f
commit ee8d52eaa7
  1. 4
      objectivec/GPBAny.pbobjc.m
  2. 12
      objectivec/GPBApi.pbobjc.m
  3. 4
      objectivec/GPBDuration.pbobjc.m
  4. 4
      objectivec/GPBEmpty.pbobjc.m
  5. 4
      objectivec/GPBFieldMask.pbobjc.m
  6. 4
      objectivec/GPBSourceContext.pbobjc.m
  7. 12
      objectivec/GPBStruct.pbobjc.m
  8. 4
      objectivec/GPBTimestamp.pbobjc.m
  9. 20
      objectivec/GPBType.pbobjc.m
  10. 36
      objectivec/GPBWrappers.pbobjc.m
  11. 71
      src/google/protobuf/util/message_differencer.cc
  12. 31
      src/google/protobuf/util/message_differencer.h

@ -91,9 +91,9 @@ typedef struct GPBAny__storage_ {
"\001\001\004\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -145,9 +145,9 @@ typedef struct GPBApi__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBApi__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -272,9 +272,9 @@ typedef struct GPBMethod__storage_ {
"\002\002\007\244\241!!\000\004\010\244\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -341,9 +341,9 @@ typedef struct GPBMixin__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBMixin__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -86,9 +86,9 @@ typedef struct GPBDuration__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDuration__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -62,9 +62,9 @@ typedef struct GPBEmpty__storage_ {
fieldCount:0
storageSize:sizeof(GPBEmpty__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -75,9 +75,9 @@ typedef struct GPBFieldMask__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFieldMask__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -75,9 +75,9 @@ typedef struct GPBSourceContext__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBSourceContext__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -115,9 +115,9 @@ typedef struct GPBStruct__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStruct__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -222,9 +222,9 @@ typedef struct GPBValue__storage_ {
[localDescriptor setupOneofs:oneofs
count:(uint32_t)(sizeof(oneofs) / sizeof(char*))
firstHasIndex:-1];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -285,9 +285,9 @@ typedef struct GPBListValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBListValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -86,9 +86,9 @@ typedef struct GPBTimestamp__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBTimestamp__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -307,9 +307,9 @@ typedef struct GPBType__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBType__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -468,9 +468,9 @@ typedef struct GPBField__storage_ {
"\001\006\004\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -593,9 +593,9 @@ typedef struct GPBEnum__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnum__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -673,9 +673,9 @@ typedef struct GPBEnumValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnumValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -730,9 +730,9 @@ typedef struct GPBOption__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBOption__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -83,9 +83,9 @@ typedef struct GPBDoubleValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDoubleValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -129,9 +129,9 @@ typedef struct GPBFloatValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFloatValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -175,9 +175,9 @@ typedef struct GPBInt64Value__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt64Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -221,9 +221,9 @@ typedef struct GPBUInt64Value__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt64Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -267,9 +267,9 @@ typedef struct GPBInt32Value__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt32Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -313,9 +313,9 @@ typedef struct GPBUInt32Value__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt32Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -358,9 +358,9 @@ typedef struct GPBBoolValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBoolValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -404,9 +404,9 @@ typedef struct GPBStringValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStringValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@ -450,9 +450,9 @@ typedef struct GPBBytesValue__storage_ {
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBytesValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
#if defined(DEBUG) && DEBUG
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;

@ -587,8 +587,10 @@ bool MessageDifferencer::CompareWithFields(
bool result = false;
FieldDescriptorArray message1_fields(message1_fields_arg.size() + 1);
FieldDescriptorArray message2_fields(message2_fields_arg.size() + 1);
std::vector<const FieldDescriptor*> message1_fields(
message1_fields_arg.size() + 1);
std::vector<const FieldDescriptor*> message2_fields(
message2_fields_arg.size() + 1);
std::copy(message1_fields_arg.cbegin(), message1_fields_arg.cend(),
message1_fields.begin());
@ -664,8 +666,10 @@ bool MessageDifferencer::Compare(const Message& message1,
}
}
FieldDescriptorArray message1_fields = RetrieveFields(message1, true);
FieldDescriptorArray message2_fields = RetrieveFields(message2, false);
std::vector<const FieldDescriptor*> message1_fields =
RetrieveFields(message1, true);
std::vector<const FieldDescriptor*> message2_fields =
RetrieveFields(message2, false);
return CompareRequestedFieldsUsingSettings(message1, message2, unpacked_any,
message1_fields, message2_fields,
@ -673,8 +677,8 @@ bool MessageDifferencer::Compare(const Message& message1,
unknown_compare_result;
}
FieldDescriptorArray MessageDifferencer::RetrieveFields(const Message& message,
bool base_message) {
std::vector<const FieldDescriptor*> MessageDifferencer::RetrieveFields(
const Message& message, bool base_message) {
const Descriptor* descriptor = message.GetDescriptor();
tmp_message_fields_.clear();
@ -698,23 +702,23 @@ FieldDescriptorArray MessageDifferencer::RetrieveFields(const Message& message,
// each list are different.
tmp_message_fields_.push_back(nullptr);
FieldDescriptorArray message_fields(tmp_message_fields_.begin(),
tmp_message_fields_.end());
std::vector<const FieldDescriptor*> message_fields(
tmp_message_fields_.begin(), tmp_message_fields_.end());
return message_fields;
}
bool MessageDifferencer::CompareRequestedFieldsUsingSettings(
const Message& message1, const Message& message2, int unpacked_any,
const FieldDescriptorArray& message1_fields,
const FieldDescriptorArray& message2_fields,
const std::vector<const FieldDescriptor*>& message1_fields,
const std::vector<const FieldDescriptor*>& message2_fields,
std::vector<SpecificField>* parent_fields) {
if (scope_ == FULL) {
if (message_field_comparison_ == EQUIVALENT) {
// We need to merge the field lists of both messages (i.e.
// we are merely checking for a difference in field values,
// rather than the addition or deletion of fields).
FieldDescriptorArray fields_union =
std::vector<const FieldDescriptor*> fields_union =
CombineFields(message1_fields, FULL, message2_fields, FULL);
return CompareWithFieldsInternal(message1, message2, unpacked_any,
fields_union, fields_union,
@ -738,7 +742,7 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings(
// but only the intersection for message2. This way, any fields
// only present in message2 will be ignored, but any fields only
// present in message1 will be marked as a difference.
FieldDescriptorArray fields_intersection =
std::vector<const FieldDescriptor*> fields_intersection =
CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL);
return CompareWithFieldsInternal(message1, message2, unpacked_any,
message1_fields, fields_intersection,
@ -747,9 +751,9 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings(
}
}
FieldDescriptorArray MessageDifferencer::CombineFields(
const FieldDescriptorArray& fields1, Scope fields1_scope,
const FieldDescriptorArray& fields2, Scope fields2_scope) {
std::vector<const FieldDescriptor*> MessageDifferencer::CombineFields(
const std::vector<const FieldDescriptor*>& fields1, Scope fields1_scope,
const std::vector<const FieldDescriptor*>& fields2, Scope fields2_scope) {
size_t index1 = 0;
size_t index2 = 0;
@ -789,16 +793,24 @@ FieldDescriptorArray MessageDifferencer::CombineFields(
tmp_message_fields_.push_back(nullptr);
FieldDescriptorArray combined_fields(tmp_message_fields_.begin(),
tmp_message_fields_.end());
std::vector<const FieldDescriptor*> combined_fields(
tmp_message_fields_.begin(), tmp_message_fields_.end());
return combined_fields;
}
// We push an element via a NOINLINE function to avoid using stack space on
// the caller for a temporary SpecificField object. They are quite large.
static PROTOBUF_NOINLINE MessageDifferencer::SpecificField& PushSpecificField(
std::vector<MessageDifferencer::SpecificField>* fields) {
fields->emplace_back();
return fields->back();
}
bool MessageDifferencer::CompareWithFieldsInternal(
const Message& message1, const Message& message2, int unpacked_any,
const FieldDescriptorArray& message1_fields,
const FieldDescriptorArray& message2_fields,
const std::vector<const FieldDescriptor*>& message1_fields,
const std::vector<const FieldDescriptor*>& message2_fields,
std::vector<SpecificField>* parent_fields) {
bool isDifferent = false;
int field_index1 = 0;
@ -823,12 +835,11 @@ bool MessageDifferencer::CompareWithFieldsInternal(
// We are ignoring field1. Report the ignore and move on to
// the next field in message1_fields.
if (reporter_ != NULL) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
specific_field.field = field1;
parent_fields->push_back(specific_field);
if (report_ignores_) {
reporter_->ReportIgnored(message1, message2, *parent_fields);
}
@ -845,7 +856,7 @@ bool MessageDifferencer::CompareWithFieldsInternal(
: 1;
for (int i = 0; i < count; ++i) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
@ -856,7 +867,6 @@ bool MessageDifferencer::CompareWithFieldsInternal(
specific_field.index = -1;
}
parent_fields->push_back(specific_field);
reporter_->ReportDeleted(message1, message2, *parent_fields);
parent_fields->pop_back();
}
@ -878,12 +888,11 @@ bool MessageDifferencer::CompareWithFieldsInternal(
// We are ignoring field2. Report the ignore and move on to
// the next field in message2_fields.
if (reporter_ != NULL) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
specific_field.field = field2;
parent_fields->push_back(specific_field);
if (report_ignores_) {
reporter_->ReportIgnored(message1, message2, *parent_fields);
}
@ -899,7 +908,7 @@ bool MessageDifferencer::CompareWithFieldsInternal(
: 1;
for (int i = 0; i < count; ++i) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1,
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
@ -916,7 +925,6 @@ bool MessageDifferencer::CompareWithFieldsInternal(
force_compare_no_presence_ &&
force_compare_no_presence_fields_.contains(specific_field.field);
parent_fields->push_back(specific_field);
reporter_->ReportAdded(message1, message2, *parent_fields);
parent_fields->pop_back();
}
@ -935,12 +943,11 @@ bool MessageDifferencer::CompareWithFieldsInternal(
if (IsIgnored(message1, message2, field1, *parent_fields)) {
// Ignore this field. Report and move on.
if (reporter_ != NULL) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
specific_field.field = field1;
parent_fields->push_back(specific_field);
if (report_ignores_) {
reporter_->ReportIgnored(message1, message2, *parent_fields);
}
@ -969,12 +976,11 @@ bool MessageDifferencer::CompareWithFieldsInternal(
}
if (reporter_ != nullptr) {
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
specific_field.field = field1;
parent_fields->push_back(specific_field);
specific_field.forced_compare_no_presence_ =
force_compare_no_presence_ &&
force_compare_no_presence_fields_.contains(field1);
@ -1387,14 +1393,13 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields(
// parent_fields is used in calls to Reporter methods.
if (parent_fields != NULL) {
// Append currently compared field to the end of parent_fields.
SpecificField specific_field;
SpecificField& specific_field = PushSpecificField(parent_fields);
specific_field.message1 = &message1;
specific_field.message2 = &message2;
specific_field.unpacked_any = unpacked_any;
specific_field.field = field;
AddSpecificIndex(&specific_field, message1, field, index1);
AddSpecificNewIndex(&specific_field, message2, field, index2);
parent_fields->push_back(specific_field);
const bool compare_result = Compare(m1, m2, false, parent_fields);
parent_fields->pop_back();
return compare_result;

@ -77,12 +77,6 @@ namespace util {
class DefaultFieldComparator;
class FieldContext; // declared below MessageDifferencer
// Defines a collection of field descriptors.
// In case of internal google codebase we are using absl::FixedArray instead
// of vector. It significantly speeds up proto comparison (by ~30%) by
// reducing the number of malloc/free operations
typedef absl::FixedArray<const FieldDescriptor*, 16> FieldDescriptorArray;
// A basic differencer that can be used to determine
// the differences between two specified Protocol Messages. If any differences
// are found, the Compare method will return false, and any differencer reporter
@ -789,17 +783,16 @@ class PROTOBUF_EXPORT MessageDifferencer {
const FieldDescriptor* field2);
// Retrieve all the set fields, including extensions.
FieldDescriptorArray RetrieveFields(const Message& message,
bool base_message);
std::vector<const FieldDescriptor*> RetrieveFields(const Message& message,
bool base_message);
// Combine the two lists of fields into the combined_fields output vector.
// All fields present in both lists will always be included in the combined
// list. Fields only present in one of the lists will only appear in the
// combined list if the corresponding fields_scope option is set to FULL.
FieldDescriptorArray CombineFields(const FieldDescriptorArray& fields1,
Scope fields1_scope,
const FieldDescriptorArray& fields2,
Scope fields2_scope);
std::vector<const FieldDescriptor*> CombineFields(
const std::vector<const FieldDescriptor*>& fields1, Scope fields1_scope,
const std::vector<const FieldDescriptor*>& fields2, Scope fields2_scope);
// Internal version of the Compare method which performs the actual
// comparison. The parent_fields vector is a vector containing field
@ -819,16 +812,16 @@ class PROTOBUF_EXPORT MessageDifferencer {
// CompareWithFieldsInternal.
bool CompareRequestedFieldsUsingSettings(
const Message& message1, const Message& message2, int unpacked_any,
const FieldDescriptorArray& message1_fields,
const FieldDescriptorArray& message2_fields,
const std::vector<const FieldDescriptor*>& message1_fields,
const std::vector<const FieldDescriptor*>& message2_fields,
std::vector<SpecificField>* parent_fields);
// Compares the specified messages with the specified field lists.
bool CompareWithFieldsInternal(const Message& message1,
const Message& message2, int unpacked_any,
const FieldDescriptorArray& message1_fields,
const FieldDescriptorArray& message2_fields,
std::vector<SpecificField>* parent_fields);
bool CompareWithFieldsInternal(
const Message& message1, const Message& message2, int unpacked_any,
const std::vector<const FieldDescriptor*>& message1_fields,
const std::vector<const FieldDescriptor*>& message2_fields,
std::vector<SpecificField>* parent_fields);
// Compares the repeated fields, and report the error.
bool CompareRepeatedField(const Message& message1, const Message& message2,

Loading…
Cancel
Save