诸暨麻将添加redis
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

1974 行
74 KiB

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: jschorr@google.com (Joseph Schorr)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <google/protobuf/util/message_differencer.h>
  34. #include <algorithm>
  35. #include <functional>
  36. #include <memory>
  37. #include <utility>
  38. #include <google/protobuf/stubs/logging.h>
  39. #include <google/protobuf/stubs/common.h>
  40. #include <google/protobuf/stubs/stringprintf.h>
  41. #include <google/protobuf/any.h>
  42. #include <google/protobuf/io/printer.h>
  43. #include <google/protobuf/io/zero_copy_stream.h>
  44. #include <google/protobuf/io/zero_copy_stream_impl.h>
  45. #include <google/protobuf/descriptor.pb.h>
  46. #include <google/protobuf/dynamic_message.h>
  47. #include <google/protobuf/text_format.h>
  48. #include <google/protobuf/util/field_comparator.h>
  49. #include <google/protobuf/stubs/strutil.h>
  50. // Always include as last one, otherwise it can break compilation
  51. #include <google/protobuf/port_def.inc>
  52. namespace google {
  53. namespace protobuf {
  54. namespace util {
  55. // A reporter to report the total number of diffs.
  56. // TODO(ykzhu): we can improve this to take into account the value differencers.
  57. class NumDiffsReporter : public google::protobuf::util::MessageDifferencer::Reporter {
  58. public:
  59. NumDiffsReporter() : num_diffs_(0) {}
  60. // Returns the total number of diffs.
  61. int32 GetNumDiffs() const { return num_diffs_; }
  62. void Reset() { num_diffs_ = 0; }
  63. // Report that a field has been added into Message2.
  64. void ReportAdded(
  65. const google::protobuf::Message& message1, const google::protobuf::Message& message2,
  66. const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
  67. field_path) override {
  68. ++num_diffs_;
  69. }
  70. // Report that a field has been deleted from Message1.
  71. void ReportDeleted(
  72. const google::protobuf::Message& message1, const google::protobuf::Message& message2,
  73. const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
  74. field_path) override {
  75. ++num_diffs_;
  76. }
  77. // Report that the value of a field has been modified.
  78. void ReportModified(
  79. const google::protobuf::Message& message1, const google::protobuf::Message& message2,
  80. const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
  81. field_path) override {
  82. ++num_diffs_;
  83. }
  84. private:
  85. int32 num_diffs_;
  86. };
  87. // When comparing a repeated field as map, MultipleFieldMapKeyComparator can
  88. // be used to specify multiple fields as key for key comparison.
  89. // Two elements of a repeated field will be regarded as having the same key
  90. // iff they have the same value for every specified key field.
  91. // Note that you can also specify only one field as key.
  92. class MessageDifferencer::MultipleFieldsMapKeyComparator
  93. : public MessageDifferencer::MapKeyComparator {
  94. public:
  95. MultipleFieldsMapKeyComparator(
  96. MessageDifferencer* message_differencer,
  97. const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths)
  98. : message_differencer_(message_differencer),
  99. key_field_paths_(key_field_paths) {
  100. GOOGLE_CHECK(!key_field_paths_.empty());
  101. for (int i = 0; i < key_field_paths_.size(); ++i) {
  102. GOOGLE_CHECK(!key_field_paths_[i].empty());
  103. }
  104. }
  105. MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer,
  106. const FieldDescriptor* key)
  107. : message_differencer_(message_differencer) {
  108. std::vector<const FieldDescriptor*> key_field_path;
  109. key_field_path.push_back(key);
  110. key_field_paths_.push_back(key_field_path);
  111. }
  112. bool IsMatch(const Message& message1, const Message& message2,
  113. const std::vector<SpecificField>& parent_fields) const override {
  114. for (int i = 0; i < key_field_paths_.size(); ++i) {
  115. if (!IsMatchInternal(message1, message2, parent_fields,
  116. key_field_paths_[i], 0)) {
  117. return false;
  118. }
  119. }
  120. return true;
  121. }
  122. private:
  123. bool IsMatchInternal(
  124. const Message& message1, const Message& message2,
  125. const std::vector<SpecificField>& parent_fields,
  126. const std::vector<const FieldDescriptor*>& key_field_path,
  127. int path_index) const {
  128. const FieldDescriptor* field = key_field_path[path_index];
  129. std::vector<SpecificField> current_parent_fields(parent_fields);
  130. if (path_index == key_field_path.size() - 1) {
  131. if (field->is_repeated()) {
  132. if (!message_differencer_->CompareRepeatedField(
  133. message1, message2, field, &current_parent_fields)) {
  134. return false;
  135. }
  136. } else {
  137. if (!message_differencer_->CompareFieldValueUsingParentFields(
  138. message1, message2, field, -1, -1, &current_parent_fields)) {
  139. return false;
  140. }
  141. }
  142. return true;
  143. } else {
  144. const Reflection* reflection1 = message1.GetReflection();
  145. const Reflection* reflection2 = message2.GetReflection();
  146. bool has_field1 = reflection1->HasField(message1, field);
  147. bool has_field2 = reflection2->HasField(message2, field);
  148. if (!has_field1 && !has_field2) {
  149. return true;
  150. }
  151. if (has_field1 != has_field2) {
  152. return false;
  153. }
  154. SpecificField specific_field;
  155. specific_field.field = field;
  156. current_parent_fields.push_back(specific_field);
  157. return IsMatchInternal(reflection1->GetMessage(message1, field),
  158. reflection2->GetMessage(message2, field),
  159. current_parent_fields, key_field_path,
  160. path_index + 1);
  161. }
  162. }
  163. MessageDifferencer* message_differencer_;
  164. std::vector<std::vector<const FieldDescriptor*> > key_field_paths_;
  165. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator);
  166. };
  167. // Preserve the order when treating repeated field as SMART_LIST. The current
  168. // implementation is to find the longest matching sequence from the first
  169. // element. The optimal solution requires to use //util/diff/lcs.h, which is
  170. // not open sourced yet. Overwrite this method if you want to have that.
  171. // TODO(ykzhu): change to use LCS once it is open sourced.
  172. void MatchIndicesPostProcessorForSmartList(
  173. std::vector<int>* match_list1, std::vector<int>* match_list2) {
  174. int last_matched_index = -1;
  175. for (int i = 0; i < match_list1->size(); ++i) {
  176. if (match_list1->at(i) < 0) {
  177. continue;
  178. }
  179. if (last_matched_index < 0 || match_list1->at(i) > last_matched_index) {
  180. last_matched_index = match_list1->at(i);
  181. } else {
  182. match_list2->at(match_list1->at(i)) = -1;
  183. match_list1->at(i) = -1;
  184. }
  185. }
  186. }
  187. MessageDifferencer::MapEntryKeyComparator::MapEntryKeyComparator(
  188. MessageDifferencer* message_differencer)
  189. : message_differencer_(message_differencer) {}
  190. bool MessageDifferencer::MapEntryKeyComparator::IsMatch(
  191. const Message& message1, const Message& message2,
  192. const std::vector<SpecificField>& parent_fields) const {
  193. // Map entry has its key in the field with tag 1. See the comment for
  194. // map_entry in MessageOptions.
  195. const FieldDescriptor* key = message1.GetDescriptor()->FindFieldByNumber(1);
  196. // If key is not present in message1 and we're doing partial comparison or if
  197. // map key is explicitly ignored treat the field as set instead,
  198. const bool treat_as_set =
  199. (message_differencer_->scope() == PARTIAL &&
  200. !message1.GetReflection()->HasField(message1, key)) ||
  201. message_differencer_->IsIgnored(message1, message2, key, parent_fields);
  202. std::vector<SpecificField> current_parent_fields(parent_fields);
  203. if (treat_as_set) {
  204. return message_differencer_->Compare(message1, message2,
  205. &current_parent_fields);
  206. }
  207. return message_differencer_->CompareFieldValueUsingParentFields(
  208. message1, message2, key, -1, -1, &current_parent_fields);
  209. }
  210. bool MessageDifferencer::Equals(const Message& message1,
  211. const Message& message2) {
  212. MessageDifferencer differencer;
  213. return differencer.Compare(message1, message2);
  214. }
  215. bool MessageDifferencer::Equivalent(const Message& message1,
  216. const Message& message2) {
  217. MessageDifferencer differencer;
  218. differencer.set_message_field_comparison(MessageDifferencer::EQUIVALENT);
  219. return differencer.Compare(message1, message2);
  220. }
  221. bool MessageDifferencer::ApproximatelyEquals(const Message& message1,
  222. const Message& message2) {
  223. MessageDifferencer differencer;
  224. differencer.set_float_comparison(MessageDifferencer::APPROXIMATE);
  225. return differencer.Compare(message1, message2);
  226. }
  227. bool MessageDifferencer::ApproximatelyEquivalent(const Message& message1,
  228. const Message& message2) {
  229. MessageDifferencer differencer;
  230. differencer.set_message_field_comparison(MessageDifferencer::EQUIVALENT);
  231. differencer.set_float_comparison(MessageDifferencer::APPROXIMATE);
  232. return differencer.Compare(message1, message2);
  233. }
  234. // ===========================================================================
  235. MessageDifferencer::MessageDifferencer()
  236. : reporter_(NULL),
  237. field_comparator_(NULL),
  238. message_field_comparison_(EQUAL),
  239. scope_(FULL),
  240. repeated_field_comparison_(AS_LIST),
  241. map_entry_key_comparator_(this),
  242. report_matches_(false),
  243. report_moves_(true),
  244. report_ignores_(true),
  245. output_string_(nullptr),
  246. match_indices_for_smart_list_callback_(
  247. MatchIndicesPostProcessorForSmartList) {}
  248. MessageDifferencer::~MessageDifferencer() {
  249. for (int i = 0; i < owned_key_comparators_.size(); ++i) {
  250. delete owned_key_comparators_[i];
  251. }
  252. for (int i = 0; i < ignore_criteria_.size(); ++i) {
  253. delete ignore_criteria_[i];
  254. }
  255. }
  256. void MessageDifferencer::set_field_comparator(FieldComparator* comparator) {
  257. GOOGLE_CHECK(comparator) << "Field comparator can't be NULL.";
  258. field_comparator_ = comparator;
  259. }
  260. void MessageDifferencer::set_message_field_comparison(
  261. MessageFieldComparison comparison) {
  262. message_field_comparison_ = comparison;
  263. }
  264. void MessageDifferencer::set_scope(Scope scope) { scope_ = scope; }
  265. MessageDifferencer::Scope MessageDifferencer::scope() { return scope_; }
  266. void MessageDifferencer::set_float_comparison(FloatComparison comparison) {
  267. default_field_comparator_.set_float_comparison(
  268. comparison == EXACT ? DefaultFieldComparator::EXACT
  269. : DefaultFieldComparator::APPROXIMATE);
  270. }
  271. void MessageDifferencer::set_repeated_field_comparison(
  272. RepeatedFieldComparison comparison) {
  273. repeated_field_comparison_ = comparison;
  274. }
  275. void MessageDifferencer::CheckRepeatedFieldComparisons(
  276. const FieldDescriptor* field,
  277. const RepeatedFieldComparison& new_comparison) {
  278. GOOGLE_CHECK(field->is_repeated())
  279. << "Field must be repeated: " << field->full_name();
  280. const MapKeyComparator* key_comparator = GetMapKeyComparator(field);
  281. GOOGLE_CHECK(key_comparator == NULL)
  282. << "Cannot treat this repeated field as both MAP and " << new_comparison
  283. << " for"
  284. << " comparison. Field name is: " << field->full_name();
  285. GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
  286. repeated_field_comparisons_.end() ||
  287. repeated_field_comparisons_[field] == new_comparison)
  288. << "Cannot treat the same field as both "
  289. << repeated_field_comparisons_[field] << " and " << new_comparison
  290. << ". Field name is: " << field->full_name();
  291. }
  292. void MessageDifferencer::TreatAsSet(const FieldDescriptor* field) {
  293. CheckRepeatedFieldComparisons(field, AS_SET);
  294. repeated_field_comparisons_[field] = AS_SET;
  295. }
  296. void MessageDifferencer::TreatAsSmartSet(const FieldDescriptor* field) {
  297. CheckRepeatedFieldComparisons(field, AS_SMART_SET);
  298. repeated_field_comparisons_[field] = AS_SMART_SET;
  299. }
  300. void MessageDifferencer::SetMatchIndicesForSmartListCallback(
  301. std::function<void(std::vector<int>*, std::vector<int>*)> callback) {
  302. match_indices_for_smart_list_callback_ = callback;
  303. }
  304. void MessageDifferencer::TreatAsList(const FieldDescriptor* field) {
  305. CheckRepeatedFieldComparisons(field, AS_LIST);
  306. repeated_field_comparisons_[field] = AS_LIST;
  307. }
  308. void MessageDifferencer::TreatAsSmartList(const FieldDescriptor* field) {
  309. CheckRepeatedFieldComparisons(field, AS_SMART_LIST);
  310. repeated_field_comparisons_[field] = AS_SMART_LIST;
  311. }
  312. void MessageDifferencer::TreatAsMap(const FieldDescriptor* field,
  313. const FieldDescriptor* key) {
  314. GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
  315. << "Field has to be message type. Field name is: " << field->full_name();
  316. GOOGLE_CHECK(key->containing_type() == field->message_type())
  317. << key->full_name()
  318. << " must be a direct subfield within the repeated field "
  319. << field->full_name() << ", not " << key->containing_type()->full_name();
  320. GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
  321. repeated_field_comparisons_.end())
  322. << "Cannot treat the same field as both "
  323. << repeated_field_comparisons_[field]
  324. << " and MAP. Field name is: " << field->full_name();
  325. MapKeyComparator* key_comparator =
  326. new MultipleFieldsMapKeyComparator(this, key);
  327. owned_key_comparators_.push_back(key_comparator);
  328. map_field_key_comparator_[field] = key_comparator;
  329. }
  330. void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey(
  331. const FieldDescriptor* field,
  332. const std::vector<const FieldDescriptor*>& key_fields) {
  333. std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
  334. for (int i = 0; i < key_fields.size(); ++i) {
  335. std::vector<const FieldDescriptor*> key_field_path;
  336. key_field_path.push_back(key_fields[i]);
  337. key_field_paths.push_back(key_field_path);
  338. }
  339. TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths);
  340. }
  341. void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey(
  342. const FieldDescriptor* field,
  343. const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) {
  344. GOOGLE_CHECK(field->is_repeated())
  345. << "Field must be repeated: " << field->full_name();
  346. GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
  347. << "Field has to be message type. Field name is: " << field->full_name();
  348. for (int i = 0; i < key_field_paths.size(); ++i) {
  349. const std::vector<const FieldDescriptor*>& key_field_path =
  350. key_field_paths[i];
  351. for (int j = 0; j < key_field_path.size(); ++j) {
  352. const FieldDescriptor* parent_field =
  353. j == 0 ? field : key_field_path[j - 1];
  354. const FieldDescriptor* child_field = key_field_path[j];
  355. GOOGLE_CHECK(child_field->containing_type() == parent_field->message_type())
  356. << child_field->full_name()
  357. << " must be a direct subfield within the field: "
  358. << parent_field->full_name();
  359. if (j != 0) {
  360. GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, parent_field->cpp_type())
  361. << parent_field->full_name() << " has to be of type message.";
  362. GOOGLE_CHECK(!parent_field->is_repeated())
  363. << parent_field->full_name() << " cannot be a repeated field.";
  364. }
  365. }
  366. }
  367. GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
  368. repeated_field_comparisons_.end())
  369. << "Cannot treat the same field as both "
  370. << repeated_field_comparisons_[field]
  371. << " and MAP. Field name is: " << field->full_name();
  372. MapKeyComparator* key_comparator =
  373. new MultipleFieldsMapKeyComparator(this, key_field_paths);
  374. owned_key_comparators_.push_back(key_comparator);
  375. map_field_key_comparator_[field] = key_comparator;
  376. }
  377. void MessageDifferencer::TreatAsMapUsingKeyComparator(
  378. const FieldDescriptor* field, const MapKeyComparator* key_comparator) {
  379. GOOGLE_CHECK(field->is_repeated())
  380. << "Field must be repeated: " << field->full_name();
  381. GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
  382. repeated_field_comparisons_.end())
  383. << "Cannot treat the same field as both "
  384. << repeated_field_comparisons_[field]
  385. << " and MAP. Field name is: " << field->full_name();
  386. map_field_key_comparator_[field] = key_comparator;
  387. }
  388. void MessageDifferencer::AddIgnoreCriteria(IgnoreCriteria* ignore_criteria) {
  389. ignore_criteria_.push_back(ignore_criteria);
  390. }
  391. void MessageDifferencer::IgnoreField(const FieldDescriptor* field) {
  392. ignored_fields_.insert(field);
  393. }
  394. void MessageDifferencer::SetFractionAndMargin(const FieldDescriptor* field,
  395. double fraction, double margin) {
  396. default_field_comparator_.SetFractionAndMargin(field, fraction, margin);
  397. }
  398. void MessageDifferencer::ReportDifferencesToString(std::string* output) {
  399. GOOGLE_DCHECK(output) << "Specified output string was NULL";
  400. output_string_ = output;
  401. output_string_->clear();
  402. }
  403. void MessageDifferencer::ReportDifferencesTo(Reporter* reporter) {
  404. // If an output string is set, clear it to prevent
  405. // it superceding the specified reporter.
  406. if (output_string_) {
  407. output_string_ = NULL;
  408. }
  409. reporter_ = reporter;
  410. }
  411. bool MessageDifferencer::FieldBefore(const FieldDescriptor* field1,
  412. const FieldDescriptor* field2) {
  413. // Handle sentinel values (i.e. make sure NULLs are always ordered
  414. // at the end of the list).
  415. if (field1 == NULL) {
  416. return false;
  417. }
  418. if (field2 == NULL) {
  419. return true;
  420. }
  421. // Always order fields by their tag number
  422. return (field1->number() < field2->number());
  423. }
  424. bool MessageDifferencer::Compare(const Message& message1,
  425. const Message& message2) {
  426. std::vector<SpecificField> parent_fields;
  427. bool result = false;
  428. // Setup the internal reporter if need be.
  429. if (output_string_) {
  430. io::StringOutputStream output_stream(output_string_);
  431. StreamReporter reporter(&output_stream);
  432. reporter_ = &reporter;
  433. result = Compare(message1, message2, &parent_fields);
  434. reporter_ = NULL;
  435. } else {
  436. result = Compare(message1, message2, &parent_fields);
  437. }
  438. return result;
  439. }
  440. bool MessageDifferencer::CompareWithFields(
  441. const Message& message1, const Message& message2,
  442. const std::vector<const FieldDescriptor*>& message1_fields_arg,
  443. const std::vector<const FieldDescriptor*>& message2_fields_arg) {
  444. if (message1.GetDescriptor() != message2.GetDescriptor()) {
  445. GOOGLE_LOG(DFATAL) << "Comparison between two messages with different "
  446. << "descriptors.";
  447. return false;
  448. }
  449. std::vector<SpecificField> parent_fields;
  450. bool result = false;
  451. FieldDescriptorArray message1_fields(message1_fields_arg.size() + 1);
  452. FieldDescriptorArray message2_fields(message2_fields_arg.size() + 1);
  453. std::copy(message1_fields_arg.cbegin(), message1_fields_arg.cend(),
  454. message1_fields.begin());
  455. std::copy(message2_fields_arg.cbegin(), message2_fields_arg.cend(),
  456. message2_fields.begin());
  457. // Append sentinel values.
  458. message1_fields[message1_fields_arg.size()] = nullptr;
  459. message2_fields[message2_fields_arg.size()] = nullptr;
  460. std::sort(message1_fields.begin(), message1_fields.end(), FieldBefore);
  461. std::sort(message2_fields.begin(), message2_fields.end(), FieldBefore);
  462. // Setup the internal reporter if need be.
  463. if (output_string_) {
  464. io::StringOutputStream output_stream(output_string_);
  465. StreamReporter reporter(&output_stream);
  466. reporter_ = &reporter;
  467. result = CompareRequestedFieldsUsingSettings(
  468. message1, message2, message1_fields, message2_fields, &parent_fields);
  469. reporter_ = NULL;
  470. } else {
  471. result = CompareRequestedFieldsUsingSettings(
  472. message1, message2, message1_fields, message2_fields, &parent_fields);
  473. }
  474. return result;
  475. }
  476. bool MessageDifferencer::Compare(const Message& message1,
  477. const Message& message2,
  478. std::vector<SpecificField>* parent_fields) {
  479. const Descriptor* descriptor1 = message1.GetDescriptor();
  480. const Descriptor* descriptor2 = message2.GetDescriptor();
  481. if (descriptor1 != descriptor2) {
  482. GOOGLE_LOG(DFATAL) << "Comparison between two messages with different "
  483. << "descriptors. " << descriptor1->full_name() << " vs "
  484. << descriptor2->full_name();
  485. return false;
  486. }
  487. // Expand google.protobuf.Any payload if possible.
  488. if (descriptor1->full_name() == internal::kAnyFullTypeName) {
  489. std::unique_ptr<Message> data1;
  490. std::unique_ptr<Message> data2;
  491. if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) {
  492. // Avoid DFATAL for different descriptors in google.protobuf.Any payloads.
  493. if (data1->GetDescriptor() != data2->GetDescriptor()) {
  494. return false;
  495. }
  496. return Compare(*data1, *data2, parent_fields);
  497. }
  498. }
  499. const Reflection* reflection1 = message1.GetReflection();
  500. const Reflection* reflection2 = message2.GetReflection();
  501. bool unknown_compare_result = true;
  502. // Ignore unknown fields in EQUIVALENT mode
  503. if (message_field_comparison_ != EQUIVALENT) {
  504. const UnknownFieldSet* unknown_field_set1 =
  505. &reflection1->GetUnknownFields(message1);
  506. const UnknownFieldSet* unknown_field_set2 =
  507. &reflection2->GetUnknownFields(message2);
  508. if (!CompareUnknownFields(message1, message2, *unknown_field_set1,
  509. *unknown_field_set2, parent_fields)) {
  510. if (reporter_ == NULL) {
  511. return false;
  512. };
  513. unknown_compare_result = false;
  514. }
  515. }
  516. FieldDescriptorArray message1_fields = RetrieveFields(message1, true);
  517. FieldDescriptorArray message2_fields = RetrieveFields(message2, false);
  518. return CompareRequestedFieldsUsingSettings(
  519. message1, message2,
  520. message1_fields, message2_fields,
  521. parent_fields) && unknown_compare_result;
  522. }
  523. FieldDescriptorArray MessageDifferencer::RetrieveFields(const Message& message,
  524. bool base_message) {
  525. const Descriptor* descriptor = message.GetDescriptor();
  526. tmp_message_fields_.clear();
  527. tmp_message_fields_.reserve(descriptor->field_count() + 1);
  528. const Reflection* reflection = message.GetReflection();
  529. if (descriptor->options().map_entry()) {
  530. if (this->scope_ == PARTIAL && base_message) {
  531. reflection->ListFields(message, &tmp_message_fields_);
  532. } else {
  533. // Map entry fields are always considered present.
  534. for (int i = 0; i < descriptor->field_count(); i++) {
  535. tmp_message_fields_.push_back(descriptor->field(i));
  536. }
  537. }
  538. } else {
  539. reflection->ListFields(message, &tmp_message_fields_);
  540. }
  541. // Add sentinel values to deal with the
  542. // case where the number of the fields in
  543. // each list are different.
  544. tmp_message_fields_.push_back(nullptr);
  545. FieldDescriptorArray message_fields(tmp_message_fields_.begin(),
  546. tmp_message_fields_.end());
  547. return message_fields;
  548. }
  549. bool MessageDifferencer::CompareRequestedFieldsUsingSettings(
  550. const Message& message1, const Message& message2,
  551. const FieldDescriptorArray& message1_fields,
  552. const FieldDescriptorArray& message2_fields,
  553. std::vector<SpecificField>* parent_fields) {
  554. if (scope_ == FULL) {
  555. if (message_field_comparison_ == EQUIVALENT) {
  556. // We need to merge the field lists of both messages (i.e.
  557. // we are merely checking for a difference in field values,
  558. // rather than the addition or deletion of fields).
  559. FieldDescriptorArray fields_union =
  560. CombineFields(message1_fields, FULL, message2_fields, FULL);
  561. return CompareWithFieldsInternal(message1, message2, fields_union,
  562. fields_union, parent_fields);
  563. } else {
  564. // Simple equality comparison, use the unaltered field lists.
  565. return CompareWithFieldsInternal(message1, message2, message1_fields,
  566. message2_fields, parent_fields);
  567. }
  568. } else {
  569. if (message_field_comparison_ == EQUIVALENT) {
  570. // We use the list of fields for message1 for both messages when
  571. // comparing. This way, extra fields in message2 are ignored,
  572. // and missing fields in message2 use their default value.
  573. return CompareWithFieldsInternal(message1, message2, message1_fields,
  574. message1_fields, parent_fields);
  575. } else {
  576. // We need to consider the full list of fields for message1
  577. // but only the intersection for message2. This way, any fields
  578. // only present in message2 will be ignored, but any fields only
  579. // present in message1 will be marked as a difference.
  580. FieldDescriptorArray fields_intersection =
  581. CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL);
  582. return CompareWithFieldsInternal(message1, message2, message1_fields,
  583. fields_intersection, parent_fields);
  584. }
  585. }
  586. }
  587. FieldDescriptorArray MessageDifferencer::CombineFields(
  588. const FieldDescriptorArray& fields1, Scope fields1_scope,
  589. const FieldDescriptorArray& fields2, Scope fields2_scope) {
  590. int index1 = 0;
  591. int index2 = 0;
  592. tmp_message_fields_.clear();
  593. while (index1 < fields1.size() && index2 < fields2.size()) {
  594. const FieldDescriptor* field1 = fields1[index1];
  595. const FieldDescriptor* field2 = fields2[index2];
  596. if (FieldBefore(field1, field2)) {
  597. if (fields1_scope == FULL) {
  598. tmp_message_fields_.push_back(fields1[index1]);
  599. }
  600. ++index1;
  601. } else if (FieldBefore(field2, field1)) {
  602. if (fields2_scope == FULL) {
  603. tmp_message_fields_.push_back(fields2[index2]);
  604. }
  605. ++index2;
  606. } else {
  607. tmp_message_fields_.push_back(fields1[index1]);
  608. ++index1;
  609. ++index2;
  610. }
  611. }
  612. tmp_message_fields_.push_back(nullptr);
  613. FieldDescriptorArray combined_fields(tmp_message_fields_.begin(),
  614. tmp_message_fields_.end());
  615. return combined_fields;
  616. }
  617. bool MessageDifferencer::CompareWithFieldsInternal(
  618. const Message& message1, const Message& message2,
  619. const FieldDescriptorArray& message1_fields,
  620. const FieldDescriptorArray& message2_fields,
  621. std::vector<SpecificField>* parent_fields) {
  622. bool isDifferent = false;
  623. int field_index1 = 0;
  624. int field_index2 = 0;
  625. const Reflection* reflection1 = message1.GetReflection();
  626. const Reflection* reflection2 = message2.GetReflection();
  627. while (true) {
  628. const FieldDescriptor* field1 = message1_fields[field_index1];
  629. const FieldDescriptor* field2 = message2_fields[field_index2];
  630. // Once we have reached sentinel values, we are done the comparison.
  631. if (field1 == NULL && field2 == NULL) {
  632. break;
  633. }
  634. // Check for differences in the field itself.
  635. if (FieldBefore(field1, field2)) {
  636. // Field 1 is not in the field list for message 2.
  637. if (IsIgnored(message1, message2, field1, *parent_fields)) {
  638. // We are ignoring field1. Report the ignore and move on to
  639. // the next field in message1_fields.
  640. if (reporter_ != NULL) {
  641. SpecificField specific_field;
  642. specific_field.field = field1;
  643. parent_fields->push_back(specific_field);
  644. if (report_ignores_) {
  645. reporter_->ReportIgnored(message1, message2, *parent_fields);
  646. }
  647. parent_fields->pop_back();
  648. }
  649. ++field_index1;
  650. continue;
  651. }
  652. if (reporter_ != NULL) {
  653. assert(field1 != NULL);
  654. int count = field1->is_repeated()
  655. ? reflection1->FieldSize(message1, field1)
  656. : 1;
  657. for (int i = 0; i < count; ++i) {
  658. SpecificField specific_field;
  659. specific_field.field = field1;
  660. specific_field.index = field1->is_repeated() ? i : -1;
  661. parent_fields->push_back(specific_field);
  662. reporter_->ReportDeleted(message1, message2, *parent_fields);
  663. parent_fields->pop_back();
  664. }
  665. isDifferent = true;
  666. } else {
  667. return false;
  668. }
  669. ++field_index1;
  670. continue;
  671. } else if (FieldBefore(field2, field1)) {
  672. // Field 2 is not in the field list for message 1.
  673. if (IsIgnored(message1, message2, field2, *parent_fields)) {
  674. // We are ignoring field2. Report the ignore and move on to
  675. // the next field in message2_fields.
  676. if (reporter_ != NULL) {
  677. SpecificField specific_field;
  678. specific_field.field = field2;
  679. parent_fields->push_back(specific_field);
  680. if (report_ignores_) {
  681. reporter_->ReportIgnored(message1, message2, *parent_fields);
  682. }
  683. parent_fields->pop_back();
  684. }
  685. ++field_index2;
  686. continue;
  687. }
  688. if (reporter_ != NULL) {
  689. int count = field2->is_repeated()
  690. ? reflection2->FieldSize(message2, field2)
  691. : 1;
  692. for (int i = 0; i < count; ++i) {
  693. SpecificField specific_field;
  694. specific_field.field = field2;
  695. specific_field.index = field2->is_repeated() ? i : -1;
  696. specific_field.new_index = specific_field.index;
  697. parent_fields->push_back(specific_field);
  698. reporter_->ReportAdded(message1, message2, *parent_fields);
  699. parent_fields->pop_back();
  700. }
  701. isDifferent = true;
  702. } else {
  703. return false;
  704. }
  705. ++field_index2;
  706. continue;
  707. }
  708. // By this point, field1 and field2 are guarenteed to point to the same
  709. // field, so we can now compare the values.
  710. if (IsIgnored(message1, message2, field1, *parent_fields)) {
  711. // Ignore this field. Report and move on.
  712. if (reporter_ != NULL) {
  713. SpecificField specific_field;
  714. specific_field.field = field1;
  715. parent_fields->push_back(specific_field);
  716. if (report_ignores_) {
  717. reporter_->ReportIgnored(message1, message2, *parent_fields);
  718. }
  719. parent_fields->pop_back();
  720. }
  721. ++field_index1;
  722. ++field_index2;
  723. continue;
  724. }
  725. bool fieldDifferent = false;
  726. assert(field1 != NULL);
  727. if (field1->is_repeated()) {
  728. fieldDifferent =
  729. !CompareRepeatedField(message1, message2, field1, parent_fields);
  730. if (fieldDifferent) {
  731. if (reporter_ == NULL) return false;
  732. isDifferent = true;
  733. }
  734. } else {
  735. fieldDifferent = !CompareFieldValueUsingParentFields(
  736. message1, message2, field1, -1, -1, parent_fields);
  737. // If we have found differences, either report them or terminate if
  738. // no reporter is present.
  739. if (fieldDifferent && reporter_ == NULL) {
  740. return false;
  741. }
  742. if (reporter_ != NULL) {
  743. SpecificField specific_field;
  744. specific_field.field = field1;
  745. parent_fields->push_back(specific_field);
  746. if (fieldDifferent) {
  747. reporter_->ReportModified(message1, message2, *parent_fields);
  748. isDifferent = true;
  749. } else if (report_matches_) {
  750. reporter_->ReportMatched(message1, message2, *parent_fields);
  751. }
  752. parent_fields->pop_back();
  753. }
  754. }
  755. // Increment the field indicies.
  756. ++field_index1;
  757. ++field_index2;
  758. }
  759. return !isDifferent;
  760. }
  761. bool MessageDifferencer::IsMatch(
  762. const FieldDescriptor* repeated_field,
  763. const MapKeyComparator* key_comparator, const Message* message1,
  764. const Message* message2, const std::vector<SpecificField>& parent_fields,
  765. Reporter* reporter, int index1, int index2) {
  766. std::vector<SpecificField> current_parent_fields(parent_fields);
  767. if (repeated_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
  768. return CompareFieldValueUsingParentFields(*message1, *message2,
  769. repeated_field, index1, index2,
  770. &current_parent_fields);
  771. }
  772. // Back up the Reporter and output_string_. They will be reset in the
  773. // following code.
  774. Reporter* backup_reporter = reporter_;
  775. std::string* output_string = output_string_;
  776. reporter_ = reporter;
  777. output_string_ = NULL;
  778. bool match;
  779. if (key_comparator == NULL) {
  780. match = CompareFieldValueUsingParentFields(*message1, *message2,
  781. repeated_field, index1, index2,
  782. &current_parent_fields);
  783. } else {
  784. const Reflection* reflection1 = message1->GetReflection();
  785. const Reflection* reflection2 = message2->GetReflection();
  786. const Message& m1 =
  787. reflection1->GetRepeatedMessage(*message1, repeated_field, index1);
  788. const Message& m2 =
  789. reflection2->GetRepeatedMessage(*message2, repeated_field, index2);
  790. SpecificField specific_field;
  791. specific_field.field = repeated_field;
  792. specific_field.index = index1;
  793. specific_field.new_index = index2;
  794. current_parent_fields.push_back(specific_field);
  795. match = key_comparator->IsMatch(m1, m2, current_parent_fields);
  796. }
  797. reporter_ = backup_reporter;
  798. output_string_ = output_string;
  799. return match;
  800. }
  801. bool MessageDifferencer::CompareRepeatedField(
  802. const Message& message1, const Message& message2,
  803. const FieldDescriptor* repeated_field,
  804. std::vector<SpecificField>* parent_fields) {
  805. // the input FieldDescriptor is guaranteed to be repeated field.
  806. const Reflection* reflection1 = message1.GetReflection();
  807. const Reflection* reflection2 = message2.GetReflection();
  808. const int count1 = reflection1->FieldSize(message1, repeated_field);
  809. const int count2 = reflection2->FieldSize(message2, repeated_field);
  810. const bool treated_as_subset = IsTreatedAsSubset(repeated_field);
  811. // If the field is not treated as subset and no detailed reports is needed,
  812. // we do a quick check on the number of the elements to avoid unnecessary
  813. // comparison.
  814. if (count1 != count2 && reporter_ == NULL && !treated_as_subset) {
  815. return false;
  816. }
  817. // A match can never be found if message1 has more items than message2.
  818. if (count1 > count2 && reporter_ == NULL) {
  819. return false;
  820. }
  821. // These two list are used for store the index of the correspondent
  822. // element in peer repeated field.
  823. std::vector<int> match_list1;
  824. std::vector<int> match_list2;
  825. const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field);
  826. bool smart_list = IsTreatedAsSmartList(repeated_field);
  827. bool simple_list = key_comparator == nullptr &&
  828. !IsTreatedAsSet(repeated_field) &&
  829. !IsTreatedAsSmartSet(repeated_field) && !smart_list;
  830. // For simple lists, we avoid matching repeated field indices, saving the
  831. // memory allocations that would otherwise be needed for match_list1 and
  832. // match_list2.
  833. if (!simple_list) {
  834. // Try to match indices of the repeated fields. Return false if match fails.
  835. if (!MatchRepeatedFieldIndices(message1, message2, repeated_field,
  836. key_comparator, *parent_fields, &match_list1,
  837. &match_list2) &&
  838. reporter_ == nullptr) {
  839. return false;
  840. }
  841. }
  842. bool fieldDifferent = false;
  843. SpecificField specific_field;
  844. specific_field.field = repeated_field;
  845. // At this point, we have already matched pairs of fields (with the reporting
  846. // to be done later). Now to check if the paired elements are different.
  847. int next_unmatched_index = 0;
  848. for (int i = 0; i < count1; i++) {
  849. if (simple_list && i >= count2) {
  850. break;
  851. }
  852. if (!simple_list && match_list1[i] == -1) {
  853. if (smart_list) {
  854. if (reporter_ == nullptr) return false;
  855. specific_field.index = i;
  856. parent_fields->push_back(specific_field);
  857. reporter_->ReportDeleted(message1, message2, *parent_fields);
  858. parent_fields->pop_back();
  859. fieldDifferent = true;
  860. // Use -2 to mark this element has been reported.
  861. match_list1[i] = -2;
  862. }
  863. continue;
  864. }
  865. if (smart_list) {
  866. for (int j = next_unmatched_index; j < match_list1[i]; ++j) {
  867. GOOGLE_CHECK_LE(0, j);
  868. if (reporter_ == nullptr) return false;
  869. specific_field.index = j;
  870. specific_field.new_index = j;
  871. parent_fields->push_back(specific_field);
  872. reporter_->ReportAdded(message1, message2, *parent_fields);
  873. parent_fields->pop_back();
  874. fieldDifferent = true;
  875. // Use -2 to mark this element has been reported.
  876. match_list2[j] = -2;
  877. }
  878. }
  879. specific_field.index = i;
  880. if (simple_list) {
  881. specific_field.new_index = i;
  882. } else {
  883. specific_field.new_index = match_list1[i];
  884. next_unmatched_index = match_list1[i] + 1;
  885. }
  886. const bool result = CompareFieldValueUsingParentFields(
  887. message1, message2, repeated_field, i, specific_field.new_index,
  888. parent_fields);
  889. // If we have found differences, either report them or terminate if
  890. // no reporter is present. Note that ReportModified, ReportMoved, and
  891. // ReportMatched are all mutually exclusive.
  892. if (!result) {
  893. if (reporter_ == NULL) return false;
  894. parent_fields->push_back(specific_field);
  895. reporter_->ReportModified(message1, message2, *parent_fields);
  896. parent_fields->pop_back();
  897. fieldDifferent = true;
  898. } else if (reporter_ != NULL &&
  899. specific_field.index != specific_field.new_index &&
  900. !specific_field.field->is_map() && report_moves_) {
  901. parent_fields->push_back(specific_field);
  902. reporter_->ReportMoved(message1, message2, *parent_fields);
  903. parent_fields->pop_back();
  904. } else if (report_matches_ && reporter_ != NULL) {
  905. parent_fields->push_back(specific_field);
  906. reporter_->ReportMatched(message1, message2, *parent_fields);
  907. parent_fields->pop_back();
  908. }
  909. }
  910. // Report any remaining additions or deletions.
  911. for (int i = 0; i < count2; ++i) {
  912. if (!simple_list && match_list2[i] != -1) continue;
  913. if (simple_list && i < count1) continue;
  914. if (!treated_as_subset) {
  915. fieldDifferent = true;
  916. }
  917. if (reporter_ == NULL) continue;
  918. specific_field.index = i;
  919. specific_field.new_index = i;
  920. parent_fields->push_back(specific_field);
  921. reporter_->ReportAdded(message1, message2, *parent_fields);
  922. parent_fields->pop_back();
  923. }
  924. for (int i = 0; i < count1; ++i) {
  925. if (!simple_list && match_list1[i] != -1) continue;
  926. if (simple_list && i < count2) continue;
  927. assert(reporter_ != NULL);
  928. specific_field.index = i;
  929. parent_fields->push_back(specific_field);
  930. reporter_->ReportDeleted(message1, message2, *parent_fields);
  931. parent_fields->pop_back();
  932. fieldDifferent = true;
  933. }
  934. return !fieldDifferent;
  935. }
  936. bool MessageDifferencer::CompareFieldValue(const Message& message1,
  937. const Message& message2,
  938. const FieldDescriptor* field,
  939. int index1, int index2) {
  940. return CompareFieldValueUsingParentFields(message1, message2, field, index1,
  941. index2, NULL);
  942. }
  943. bool MessageDifferencer::CompareFieldValueUsingParentFields(
  944. const Message& message1, const Message& message2,
  945. const FieldDescriptor* field, int index1, int index2,
  946. std::vector<SpecificField>* parent_fields) {
  947. FieldContext field_context(parent_fields);
  948. FieldComparator::ComparisonResult result = GetFieldComparisonResult(
  949. message1, message2, field, index1, index2, &field_context);
  950. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  951. result == FieldComparator::RECURSE) {
  952. // Get the nested messages and compare them using one of the Compare
  953. // methods.
  954. const Reflection* reflection1 = message1.GetReflection();
  955. const Reflection* reflection2 = message2.GetReflection();
  956. const Message& m1 =
  957. field->is_repeated()
  958. ? reflection1->GetRepeatedMessage(message1, field, index1)
  959. : reflection1->GetMessage(message1, field);
  960. const Message& m2 =
  961. field->is_repeated()
  962. ? reflection2->GetRepeatedMessage(message2, field, index2)
  963. : reflection2->GetMessage(message2, field);
  964. // parent_fields is used in calls to Reporter methods.
  965. if (parent_fields != NULL) {
  966. // Append currently compared field to the end of parent_fields.
  967. SpecificField specific_field;
  968. specific_field.field = field;
  969. specific_field.index = index1;
  970. specific_field.new_index = index2;
  971. parent_fields->push_back(specific_field);
  972. const bool compare_result = Compare(m1, m2, parent_fields);
  973. parent_fields->pop_back();
  974. return compare_result;
  975. } else {
  976. // Recreates parent_fields as if m1 and m2 had no parents.
  977. return Compare(m1, m2);
  978. }
  979. } else {
  980. return (result == FieldComparator::SAME);
  981. }
  982. }
  983. bool MessageDifferencer::CheckPathChanged(
  984. const std::vector<SpecificField>& field_path) {
  985. for (int i = 0; i < field_path.size(); ++i) {
  986. // Don't check indexes for map entries -- maps are unordered.
  987. if (field_path[i].field != NULL && field_path[i].field->is_map()) continue;
  988. if (field_path[i].index != field_path[i].new_index) return true;
  989. }
  990. return false;
  991. }
  992. bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) {
  993. if (!field->is_repeated()) return false;
  994. if (repeated_field_comparisons_.find(field) !=
  995. repeated_field_comparisons_.end()) {
  996. return repeated_field_comparisons_[field] == AS_SET;
  997. }
  998. return repeated_field_comparison_ == AS_SET;
  999. }
  1000. bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) {
  1001. if (!field->is_repeated()) return false;
  1002. if (repeated_field_comparisons_.find(field) !=
  1003. repeated_field_comparisons_.end()) {
  1004. return repeated_field_comparisons_[field] == AS_SMART_SET;
  1005. }
  1006. return repeated_field_comparison_ == AS_SMART_SET;
  1007. }
  1008. bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) {
  1009. if (!field->is_repeated()) return false;
  1010. if (repeated_field_comparisons_.find(field) !=
  1011. repeated_field_comparisons_.end()) {
  1012. return repeated_field_comparisons_[field] == AS_SMART_LIST;
  1013. }
  1014. return repeated_field_comparison_ == AS_SMART_LIST;
  1015. }
  1016. bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) {
  1017. return scope_ == PARTIAL &&
  1018. (IsTreatedAsSet(field) || GetMapKeyComparator(field) != NULL);
  1019. }
  1020. bool MessageDifferencer::IsIgnored(
  1021. const Message& message1, const Message& message2,
  1022. const FieldDescriptor* field,
  1023. const std::vector<SpecificField>& parent_fields) {
  1024. if (ignored_fields_.find(field) != ignored_fields_.end()) {
  1025. return true;
  1026. }
  1027. for (int i = 0; i < ignore_criteria_.size(); ++i) {
  1028. if (ignore_criteria_[i]->IsIgnored(message1, message2, field,
  1029. parent_fields)) {
  1030. return true;
  1031. }
  1032. }
  1033. return false;
  1034. }
  1035. bool MessageDifferencer::IsUnknownFieldIgnored(
  1036. const Message& message1, const Message& message2,
  1037. const SpecificField& field,
  1038. const std::vector<SpecificField>& parent_fields) {
  1039. for (int i = 0; i < ignore_criteria_.size(); ++i) {
  1040. if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field,
  1041. parent_fields)) {
  1042. return true;
  1043. }
  1044. }
  1045. return false;
  1046. }
  1047. const MessageDifferencer::MapKeyComparator*
  1048. MessageDifferencer ::GetMapKeyComparator(const FieldDescriptor* field) const {
  1049. if (!field->is_repeated()) return NULL;
  1050. FieldKeyComparatorMap::const_iterator it =
  1051. map_field_key_comparator_.find(field);
  1052. if (it != map_field_key_comparator_.end()) {
  1053. return it->second;
  1054. }
  1055. if (field->is_map()) {
  1056. // field cannot already be treated as list or set since TreatAsList() and
  1057. // TreatAsSet() call GetMapKeyComparator() and fail if it returns non-NULL.
  1058. return &map_entry_key_comparator_;
  1059. }
  1060. return NULL;
  1061. }
  1062. namespace {
  1063. typedef std::pair<int, const UnknownField*> IndexUnknownFieldPair;
  1064. struct UnknownFieldOrdering {
  1065. inline bool operator()(const IndexUnknownFieldPair& a,
  1066. const IndexUnknownFieldPair& b) const {
  1067. if (a.second->number() < b.second->number()) return true;
  1068. if (a.second->number() > b.second->number()) return false;
  1069. return a.second->type() < b.second->type();
  1070. }
  1071. };
  1072. } // namespace
  1073. bool MessageDifferencer::UnpackAny(const Message& any,
  1074. std::unique_ptr<Message>* data) {
  1075. const Reflection* reflection = any.GetReflection();
  1076. const FieldDescriptor* type_url_field;
  1077. const FieldDescriptor* value_field;
  1078. if (!internal::GetAnyFieldDescriptors(any, &type_url_field, &value_field)) {
  1079. return false;
  1080. }
  1081. const std::string& type_url = reflection->GetString(any, type_url_field);
  1082. std::string full_type_name;
  1083. if (!internal::ParseAnyTypeUrl(type_url, &full_type_name)) {
  1084. return false;
  1085. }
  1086. const Descriptor* desc =
  1087. any.GetDescriptor()->file()->pool()->FindMessageTypeByName(
  1088. full_type_name);
  1089. if (desc == NULL) {
  1090. GOOGLE_DLOG(ERROR) << "Proto type '" << full_type_name << "' not found";
  1091. return false;
  1092. }
  1093. if (dynamic_message_factory_ == NULL) {
  1094. dynamic_message_factory_.reset(new DynamicMessageFactory());
  1095. }
  1096. data->reset(dynamic_message_factory_->GetPrototype(desc)->New());
  1097. std::string serialized_value = reflection->GetString(any, value_field);
  1098. if (!(*data)->ParseFromString(serialized_value)) {
  1099. GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name;
  1100. return false;
  1101. }
  1102. return true;
  1103. }
  1104. bool MessageDifferencer::CompareUnknownFields(
  1105. const Message& message1, const Message& message2,
  1106. const UnknownFieldSet& unknown_field_set1,
  1107. const UnknownFieldSet& unknown_field_set2,
  1108. std::vector<SpecificField>* parent_field) {
  1109. // Ignore unknown fields in EQUIVALENT mode.
  1110. if (message_field_comparison_ == EQUIVALENT) return true;
  1111. if (unknown_field_set1.empty() && unknown_field_set2.empty()) {
  1112. return true;
  1113. }
  1114. bool is_different = false;
  1115. // We first sort the unknown fields by field number and type (in other words,
  1116. // in tag order), making sure to preserve ordering of values with the same
  1117. // tag. This allows us to report only meaningful differences between the
  1118. // two sets -- that is, differing values for the same tag. We use
  1119. // IndexUnknownFieldPairs to keep track of the field's original index for
  1120. // reporting purposes.
  1121. std::vector<IndexUnknownFieldPair> fields1; // unknown_field_set1, sorted
  1122. std::vector<IndexUnknownFieldPair> fields2; // unknown_field_set2, sorted
  1123. fields1.reserve(unknown_field_set1.field_count());
  1124. fields2.reserve(unknown_field_set2.field_count());
  1125. for (int i = 0; i < unknown_field_set1.field_count(); i++) {
  1126. fields1.push_back(std::make_pair(i, &unknown_field_set1.field(i)));
  1127. }
  1128. for (int i = 0; i < unknown_field_set2.field_count(); i++) {
  1129. fields2.push_back(std::make_pair(i, &unknown_field_set2.field(i)));
  1130. }
  1131. UnknownFieldOrdering is_before;
  1132. std::stable_sort(fields1.begin(), fields1.end(), is_before);
  1133. std::stable_sort(fields2.begin(), fields2.end(), is_before);
  1134. // In order to fill in SpecificField::index, we have to keep track of how
  1135. // many values we've seen with the same field number and type.
  1136. // current_repeated points at the first field in this range, and
  1137. // current_repeated_start{1,2} are the indexes of the first field in the
  1138. // range within fields1 and fields2.
  1139. const UnknownField* current_repeated = NULL;
  1140. int current_repeated_start1 = 0;
  1141. int current_repeated_start2 = 0;
  1142. // Now that we have two sorted lists, we can detect fields which appear only
  1143. // in one list or the other by traversing them simultaneously.
  1144. int index1 = 0;
  1145. int index2 = 0;
  1146. while (index1 < fields1.size() || index2 < fields2.size()) {
  1147. enum {
  1148. ADDITION,
  1149. DELETION,
  1150. MODIFICATION,
  1151. COMPARE_GROUPS,
  1152. NO_CHANGE
  1153. } change_type;
  1154. // focus_field is the field we're currently reporting on. (In the case
  1155. // of a modification, it's the field on the left side.)
  1156. const UnknownField* focus_field;
  1157. bool match = false;
  1158. if (index2 == fields2.size() ||
  1159. (index1 < fields1.size() &&
  1160. is_before(fields1[index1], fields2[index2]))) {
  1161. // fields1[index1] is not present in fields2.
  1162. change_type = DELETION;
  1163. focus_field = fields1[index1].second;
  1164. } else if (index1 == fields1.size() ||
  1165. is_before(fields2[index2], fields1[index1])) {
  1166. // fields2[index2] is not present in fields1.
  1167. if (scope_ == PARTIAL) {
  1168. // Ignore.
  1169. ++index2;
  1170. continue;
  1171. }
  1172. change_type = ADDITION;
  1173. focus_field = fields2[index2].second;
  1174. } else {
  1175. // Field type and number are the same. See if the values differ.
  1176. change_type = MODIFICATION;
  1177. focus_field = fields1[index1].second;
  1178. switch (focus_field->type()) {
  1179. case UnknownField::TYPE_VARINT:
  1180. match = fields1[index1].second->varint() ==
  1181. fields2[index2].second->varint();
  1182. break;
  1183. case UnknownField::TYPE_FIXED32:
  1184. match = fields1[index1].second->fixed32() ==
  1185. fields2[index2].second->fixed32();
  1186. break;
  1187. case UnknownField::TYPE_FIXED64:
  1188. match = fields1[index1].second->fixed64() ==
  1189. fields2[index2].second->fixed64();
  1190. break;
  1191. case UnknownField::TYPE_LENGTH_DELIMITED:
  1192. match = fields1[index1].second->length_delimited() ==
  1193. fields2[index2].second->length_delimited();
  1194. break;
  1195. case UnknownField::TYPE_GROUP:
  1196. // We must deal with this later, after building the SpecificField.
  1197. change_type = COMPARE_GROUPS;
  1198. break;
  1199. }
  1200. if (match && change_type != COMPARE_GROUPS) {
  1201. change_type = NO_CHANGE;
  1202. }
  1203. }
  1204. if (current_repeated == NULL ||
  1205. focus_field->number() != current_repeated->number() ||
  1206. focus_field->type() != current_repeated->type()) {
  1207. // We've started a new repeated field.
  1208. current_repeated = focus_field;
  1209. current_repeated_start1 = index1;
  1210. current_repeated_start2 = index2;
  1211. }
  1212. if (change_type == NO_CHANGE && reporter_ == NULL) {
  1213. // Fields were already compared and matched and we have no reporter.
  1214. ++index1;
  1215. ++index2;
  1216. continue;
  1217. }
  1218. // Build the SpecificField. This is slightly complicated.
  1219. SpecificField specific_field;
  1220. specific_field.unknown_field_number = focus_field->number();
  1221. specific_field.unknown_field_type = focus_field->type();
  1222. specific_field.unknown_field_set1 = &unknown_field_set1;
  1223. specific_field.unknown_field_set2 = &unknown_field_set2;
  1224. if (change_type != ADDITION) {
  1225. specific_field.unknown_field_index1 = fields1[index1].first;
  1226. }
  1227. if (change_type != DELETION) {
  1228. specific_field.unknown_field_index2 = fields2[index2].first;
  1229. }
  1230. // Calculate the field index.
  1231. if (change_type == ADDITION) {
  1232. specific_field.index = index2 - current_repeated_start2;
  1233. specific_field.new_index = index2 - current_repeated_start2;
  1234. } else {
  1235. specific_field.index = index1 - current_repeated_start1;
  1236. specific_field.new_index = index2 - current_repeated_start2;
  1237. }
  1238. if (IsUnknownFieldIgnored(message1, message2, specific_field,
  1239. *parent_field)) {
  1240. if (reporter_ != NULL) {
  1241. parent_field->push_back(specific_field);
  1242. reporter_->ReportUnknownFieldIgnored(message1, message2, *parent_field);
  1243. parent_field->pop_back();
  1244. }
  1245. return true;
  1246. }
  1247. if (change_type == ADDITION || change_type == DELETION ||
  1248. change_type == MODIFICATION) {
  1249. if (reporter_ == NULL) {
  1250. // We found a difference and we have no reporter.
  1251. return false;
  1252. }
  1253. is_different = true;
  1254. }
  1255. parent_field->push_back(specific_field);
  1256. switch (change_type) {
  1257. case ADDITION:
  1258. reporter_->ReportAdded(message1, message2, *parent_field);
  1259. ++index2;
  1260. break;
  1261. case DELETION:
  1262. reporter_->ReportDeleted(message1, message2, *parent_field);
  1263. ++index1;
  1264. break;
  1265. case MODIFICATION:
  1266. reporter_->ReportModified(message1, message2, *parent_field);
  1267. ++index1;
  1268. ++index2;
  1269. break;
  1270. case COMPARE_GROUPS:
  1271. if (!CompareUnknownFields(
  1272. message1, message2, fields1[index1].second->group(),
  1273. fields2[index2].second->group(), parent_field)) {
  1274. if (reporter_ == NULL) return false;
  1275. is_different = true;
  1276. reporter_->ReportModified(message1, message2, *parent_field);
  1277. }
  1278. ++index1;
  1279. ++index2;
  1280. break;
  1281. case NO_CHANGE:
  1282. ++index1;
  1283. ++index2;
  1284. if (report_matches_) {
  1285. reporter_->ReportMatched(message1, message2, *parent_field);
  1286. }
  1287. }
  1288. parent_field->pop_back();
  1289. }
  1290. return !is_different;
  1291. }
  1292. namespace {
  1293. // Find maximum bipartite matching using the argumenting path algorithm.
  1294. class MaximumMatcher {
  1295. public:
  1296. typedef std::function<bool(int, int)> NodeMatchCallback;
  1297. // MaximumMatcher takes ownership of the passed in callback and uses it to
  1298. // determine whether a node on the left side of the bipartial graph matches
  1299. // a node on the right side. count1 is the number of nodes on the left side
  1300. // of the graph and count2 to is the number of nodes on the right side.
  1301. // Every node is referred to using 0-based indices.
  1302. // If a maximum match is found, the result will be stored in match_list1 and
  1303. // match_list2. match_list1[i] == j means the i-th node on the left side is
  1304. // matched to the j-th node on the right side and match_list2[x] == y means
  1305. // the x-th node on the right side is matched to y-th node on the left side.
  1306. // match_list1[i] == -1 means the node is not matched. Same with match_list2.
  1307. MaximumMatcher(int count1, int count2, NodeMatchCallback callback,
  1308. std::vector<int>* match_list1, std::vector<int>* match_list2);
  1309. // Find a maximum match and return the number of matched node pairs.
  1310. // If early_return is true, this method will return 0 immediately when it
  1311. // finds that not all nodes on the left side can be matched.
  1312. int FindMaximumMatch(bool early_return);
  1313. private:
  1314. // Determines whether the node on the left side of the bipartial graph
  1315. // matches the one on the right side.
  1316. bool Match(int left, int right);
  1317. // Find an argumenting path starting from the node v on the left side. If a
  1318. // path can be found, update match_list2_ to reflect the path and return
  1319. // true.
  1320. bool FindArgumentPathDFS(int v, std::vector<bool>* visited);
  1321. int count1_;
  1322. int count2_;
  1323. NodeMatchCallback match_callback_;
  1324. std::map<std::pair<int, int>, bool> cached_match_results_;
  1325. std::vector<int>* match_list1_;
  1326. std::vector<int>* match_list2_;
  1327. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MaximumMatcher);
  1328. };
  1329. MaximumMatcher::MaximumMatcher(int count1, int count2,
  1330. NodeMatchCallback callback,
  1331. std::vector<int>* match_list1,
  1332. std::vector<int>* match_list2)
  1333. : count1_(count1),
  1334. count2_(count2),
  1335. match_callback_(std::move(callback)),
  1336. match_list1_(match_list1),
  1337. match_list2_(match_list2) {
  1338. match_list1_->assign(count1, -1);
  1339. match_list2_->assign(count2, -1);
  1340. }
  1341. int MaximumMatcher::FindMaximumMatch(bool early_return) {
  1342. int result = 0;
  1343. for (int i = 0; i < count1_; ++i) {
  1344. std::vector<bool> visited(count1_);
  1345. if (FindArgumentPathDFS(i, &visited)) {
  1346. ++result;
  1347. } else if (early_return) {
  1348. return 0;
  1349. }
  1350. }
  1351. // Backfill match_list1_ as we only filled match_list2_ when finding
  1352. // argumenting pathes.
  1353. for (int i = 0; i < count2_; ++i) {
  1354. if ((*match_list2_)[i] != -1) {
  1355. (*match_list1_)[(*match_list2_)[i]] = i;
  1356. }
  1357. }
  1358. return result;
  1359. }
  1360. bool MaximumMatcher::Match(int left, int right) {
  1361. std::pair<int, int> p(left, right);
  1362. std::map<std::pair<int, int>, bool>::iterator it =
  1363. cached_match_results_.find(p);
  1364. if (it != cached_match_results_.end()) {
  1365. return it->second;
  1366. }
  1367. cached_match_results_[p] = match_callback_(left, right);
  1368. return cached_match_results_[p];
  1369. }
  1370. bool MaximumMatcher::FindArgumentPathDFS(int v, std::vector<bool>* visited) {
  1371. (*visited)[v] = true;
  1372. // We try to match those un-matched nodes on the right side first. This is
  1373. // the step that the navie greedy matching algorithm uses. In the best cases
  1374. // where the greedy algorithm can find a maximum matching, we will always
  1375. // find a match in this step and the performance will be identical to the
  1376. // greedy algorithm.
  1377. for (int i = 0; i < count2_; ++i) {
  1378. int matched = (*match_list2_)[i];
  1379. if (matched == -1 && Match(v, i)) {
  1380. (*match_list2_)[i] = v;
  1381. return true;
  1382. }
  1383. }
  1384. // Then we try those already matched nodes and see if we can find an
  1385. // alternaive match for the node matched to them.
  1386. // The greedy algorithm will stop before this and fail to produce the
  1387. // correct result.
  1388. for (int i = 0; i < count2_; ++i) {
  1389. int matched = (*match_list2_)[i];
  1390. if (matched != -1 && Match(v, i)) {
  1391. if (!(*visited)[matched] && FindArgumentPathDFS(matched, visited)) {
  1392. (*match_list2_)[i] = v;
  1393. return true;
  1394. }
  1395. }
  1396. }
  1397. return false;
  1398. }
  1399. } // namespace
  1400. bool MessageDifferencer::MatchRepeatedFieldIndices(
  1401. const Message& message1, const Message& message2,
  1402. const FieldDescriptor* repeated_field,
  1403. const MapKeyComparator* key_comparator,
  1404. const std::vector<SpecificField>& parent_fields,
  1405. std::vector<int>* match_list1, std::vector<int>* match_list2) {
  1406. const int count1 =
  1407. message1.GetReflection()->FieldSize(message1, repeated_field);
  1408. const int count2 =
  1409. message2.GetReflection()->FieldSize(message2, repeated_field);
  1410. const bool is_treated_as_smart_set = IsTreatedAsSmartSet(repeated_field);
  1411. match_list1->assign(count1, -1);
  1412. match_list2->assign(count2, -1);
  1413. // Ensure that we don't report differences during the matching process. Since
  1414. // field comparators could potentially use this message differencer object to
  1415. // perform further comparisons, turn off reporting here and re-enable it
  1416. // before returning.
  1417. Reporter* reporter = reporter_;
  1418. reporter_ = NULL;
  1419. NumDiffsReporter num_diffs_reporter;
  1420. std::vector<int32> num_diffs_list1;
  1421. if (is_treated_as_smart_set) {
  1422. num_diffs_list1.assign(count1, kint32max);
  1423. }
  1424. bool success = true;
  1425. // Find potential match if this is a special repeated field.
  1426. if (scope_ == PARTIAL) {
  1427. // When partial matching is enabled, Compare(a, b) && Compare(a, c)
  1428. // doesn't necessarily imply Compare(b, c). Therefore a naive greedy
  1429. // algorithm will fail to find a maximum matching.
  1430. // Here we use the augmenting path algorithm.
  1431. auto callback = [&](int i1, int i2) {
  1432. return IsMatch(repeated_field, key_comparator, &message1, &message2,
  1433. parent_fields, nullptr, i1, i2);
  1434. };
  1435. MaximumMatcher matcher(count1, count2, std::move(callback), match_list1,
  1436. match_list2);
  1437. // If diff info is not needed, we should end the matching process as
  1438. // soon as possible if not all items can be matched.
  1439. bool early_return = (reporter == nullptr);
  1440. int match_count = matcher.FindMaximumMatch(early_return);
  1441. if (match_count != count1 && early_return) return false;
  1442. success = success && (match_count == count1);
  1443. } else {
  1444. int start_offset = 0;
  1445. // If the two repeated fields are treated as sets, optimize for the case
  1446. // where both start with same items stored in the same order.
  1447. if (IsTreatedAsSet(repeated_field) || is_treated_as_smart_set ||
  1448. IsTreatedAsSmartList(repeated_field)) {
  1449. start_offset = std::min(count1, count2);
  1450. for (int i = 0; i < count1 && i < count2; i++) {
  1451. if (IsMatch(repeated_field, key_comparator, &message1, &message2,
  1452. parent_fields, nullptr, i, i)) {
  1453. match_list1->at(i) = i;
  1454. match_list2->at(i) = i;
  1455. } else {
  1456. start_offset = i;
  1457. break;
  1458. }
  1459. }
  1460. }
  1461. for (int i = start_offset; i < count1; ++i) {
  1462. // Indicates any matched elements for this repeated field.
  1463. bool match = false;
  1464. int matched_j = -1;
  1465. for (int j = start_offset; j < count2; j++) {
  1466. if (match_list2->at(j) != -1) {
  1467. if (!is_treated_as_smart_set || num_diffs_list1[i] == 0 ||
  1468. num_diffs_list1[match_list2->at(j)] == 0) {
  1469. continue;
  1470. }
  1471. }
  1472. if (is_treated_as_smart_set) {
  1473. num_diffs_reporter.Reset();
  1474. match = IsMatch(repeated_field, key_comparator, &message1, &message2,
  1475. parent_fields, &num_diffs_reporter, i, j);
  1476. } else {
  1477. match = IsMatch(repeated_field, key_comparator, &message1, &message2,
  1478. parent_fields, nullptr, i, j);
  1479. }
  1480. if (is_treated_as_smart_set) {
  1481. if (match) {
  1482. num_diffs_list1[i] = 0;
  1483. } else if (repeated_field->cpp_type() ==
  1484. FieldDescriptor::CPPTYPE_MESSAGE) {
  1485. // Replace with the one with fewer diffs.
  1486. const int32 num_diffs = num_diffs_reporter.GetNumDiffs();
  1487. if (num_diffs < num_diffs_list1[i]) {
  1488. // If j has been already matched to some element, ensure the
  1489. // current num_diffs is smaller.
  1490. if (match_list2->at(j) == -1 ||
  1491. num_diffs < num_diffs_list1[match_list2->at(j)]) {
  1492. num_diffs_list1[i] = num_diffs;
  1493. match = true;
  1494. }
  1495. }
  1496. }
  1497. }
  1498. if (match) {
  1499. matched_j = j;
  1500. if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
  1501. break;
  1502. }
  1503. }
  1504. }
  1505. match = (matched_j != -1);
  1506. if (match) {
  1507. if (is_treated_as_smart_set && match_list2->at(matched_j) != -1) {
  1508. // This is to revert the previously matched index in list2.
  1509. match_list1->at(match_list2->at(matched_j)) = -1;
  1510. match = false;
  1511. }
  1512. match_list1->at(i) = matched_j;
  1513. match_list2->at(matched_j) = i;
  1514. }
  1515. if (!match && reporter == nullptr) return false;
  1516. success = success && match;
  1517. }
  1518. }
  1519. if (IsTreatedAsSmartList(repeated_field)) {
  1520. match_indices_for_smart_list_callback_(match_list1, match_list2);
  1521. }
  1522. reporter_ = reporter;
  1523. return success;
  1524. }
  1525. FieldComparator::ComparisonResult MessageDifferencer::GetFieldComparisonResult(
  1526. const Message& message1, const Message& message2,
  1527. const FieldDescriptor* field, int index1, int index2,
  1528. const FieldContext* field_context) {
  1529. FieldComparator* comparator = field_comparator_ != NULL
  1530. ? field_comparator_
  1531. : &default_field_comparator_;
  1532. return comparator->Compare(message1, message2, field, index1, index2,
  1533. field_context);
  1534. }
  1535. // ===========================================================================
  1536. MessageDifferencer::Reporter::Reporter() {}
  1537. MessageDifferencer::Reporter::~Reporter() {}
  1538. // ===========================================================================
  1539. MessageDifferencer::MapKeyComparator::MapKeyComparator() {}
  1540. MessageDifferencer::MapKeyComparator::~MapKeyComparator() {}
  1541. // ===========================================================================
  1542. MessageDifferencer::IgnoreCriteria::IgnoreCriteria() {}
  1543. MessageDifferencer::IgnoreCriteria::~IgnoreCriteria() {}
  1544. // ===========================================================================
  1545. // Note that the printer's delimiter is not used, because if we are given a
  1546. // printer, we don't know its delimiter.
  1547. MessageDifferencer::StreamReporter::StreamReporter(
  1548. io::ZeroCopyOutputStream* output)
  1549. : printer_(new io::Printer(output, '$')),
  1550. delete_printer_(true),
  1551. report_modified_aggregates_(false) {}
  1552. MessageDifferencer::StreamReporter::StreamReporter(io::Printer* printer)
  1553. : printer_(printer),
  1554. delete_printer_(false),
  1555. report_modified_aggregates_(false) {}
  1556. MessageDifferencer::StreamReporter::~StreamReporter() {
  1557. if (delete_printer_) delete printer_;
  1558. }
  1559. void MessageDifferencer::StreamReporter::PrintPath(
  1560. const std::vector<SpecificField>& field_path, bool left_side) {
  1561. for (int i = 0; i < field_path.size(); ++i) {
  1562. if (i > 0) {
  1563. printer_->Print(".");
  1564. }
  1565. SpecificField specific_field = field_path[i];
  1566. if (specific_field.field != NULL) {
  1567. if (specific_field.field->is_extension()) {
  1568. printer_->Print("($name$)", "name", specific_field.field->full_name());
  1569. } else {
  1570. printer_->PrintRaw(specific_field.field->name());
  1571. }
  1572. if (specific_field.field->is_map()) {
  1573. // Don't print index in a map field; they are semantically unordered.
  1574. continue;
  1575. }
  1576. } else {
  1577. printer_->PrintRaw(StrCat(specific_field.unknown_field_number));
  1578. }
  1579. if (left_side && specific_field.index >= 0) {
  1580. printer_->Print("[$name$]", "name", StrCat(specific_field.index));
  1581. }
  1582. if (!left_side && specific_field.new_index >= 0) {
  1583. printer_->Print("[$name$]", "name",
  1584. StrCat(specific_field.new_index));
  1585. }
  1586. }
  1587. }
  1588. void MessageDifferencer::StreamReporter::PrintPath(
  1589. const std::vector<SpecificField>& field_path, bool left_side,
  1590. const Message& message) {
  1591. PrintPath(field_path, left_side);
  1592. }
  1593. void MessageDifferencer::StreamReporter::PrintValue(
  1594. const Message& message, const std::vector<SpecificField>& field_path,
  1595. bool left_side) {
  1596. const SpecificField& specific_field = field_path.back();
  1597. const FieldDescriptor* field = specific_field.field;
  1598. if (field != NULL) {
  1599. std::string output;
  1600. int index = left_side ? specific_field.index : specific_field.new_index;
  1601. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  1602. const Reflection* reflection = message.GetReflection();
  1603. const Message& field_message =
  1604. field->is_repeated()
  1605. ? reflection->GetRepeatedMessage(message, field, index)
  1606. : reflection->GetMessage(message, field);
  1607. output = field_message.ShortDebugString();
  1608. if (output.empty()) {
  1609. printer_->Print("{ }");
  1610. } else {
  1611. printer_->Print("{ $name$ }", "name", output);
  1612. }
  1613. } else {
  1614. TextFormat::PrintFieldValueToString(message, field, index, &output);
  1615. printer_->PrintRaw(output);
  1616. }
  1617. } else {
  1618. const UnknownFieldSet* unknown_fields =
  1619. (left_side ? specific_field.unknown_field_set1
  1620. : specific_field.unknown_field_set2);
  1621. const UnknownField* unknown_field =
  1622. &unknown_fields->field(left_side ? specific_field.unknown_field_index1
  1623. : specific_field.unknown_field_index2);
  1624. PrintUnknownFieldValue(unknown_field);
  1625. }
  1626. }
  1627. void MessageDifferencer::StreamReporter::PrintUnknownFieldValue(
  1628. const UnknownField* unknown_field) {
  1629. GOOGLE_CHECK(unknown_field != NULL) << " Cannot print NULL unknown_field.";
  1630. std::string output;
  1631. switch (unknown_field->type()) {
  1632. case UnknownField::TYPE_VARINT:
  1633. output = StrCat(unknown_field->varint());
  1634. break;
  1635. case UnknownField::TYPE_FIXED32:
  1636. output = StrCat(
  1637. "0x", strings::Hex(unknown_field->fixed32(), strings::ZERO_PAD_8));
  1638. break;
  1639. case UnknownField::TYPE_FIXED64:
  1640. output = StrCat(
  1641. "0x", strings::Hex(unknown_field->fixed64(), strings::ZERO_PAD_16));
  1642. break;
  1643. case UnknownField::TYPE_LENGTH_DELIMITED:
  1644. output = StringPrintf(
  1645. "\"%s\"", CEscape(unknown_field->length_delimited()).c_str());
  1646. break;
  1647. case UnknownField::TYPE_GROUP:
  1648. // TODO(kenton): Print the contents of the group like we do for
  1649. // messages. Requires an equivalent of ShortDebugString() for
  1650. // UnknownFieldSet.
  1651. output = "{ ... }";
  1652. break;
  1653. }
  1654. printer_->PrintRaw(output);
  1655. }
  1656. void MessageDifferencer::StreamReporter::Print(const std::string& str) {
  1657. printer_->Print(str.c_str());
  1658. }
  1659. void MessageDifferencer::StreamReporter::ReportAdded(
  1660. const Message& message1, const Message& message2,
  1661. const std::vector<SpecificField>& field_path) {
  1662. printer_->Print("added: ");
  1663. PrintPath(field_path, false, message2);
  1664. printer_->Print(": ");
  1665. PrintValue(message2, field_path, false);
  1666. printer_->Print("\n"); // Print for newlines.
  1667. }
  1668. void MessageDifferencer::StreamReporter::ReportDeleted(
  1669. const Message& message1, const Message& message2,
  1670. const std::vector<SpecificField>& field_path) {
  1671. printer_->Print("deleted: ");
  1672. PrintPath(field_path, true, message1);
  1673. printer_->Print(": ");
  1674. PrintValue(message1, field_path, true);
  1675. printer_->Print("\n"); // Print for newlines
  1676. }
  1677. void MessageDifferencer::StreamReporter::ReportModified(
  1678. const Message& message1, const Message& message2,
  1679. const std::vector<SpecificField>& field_path) {
  1680. if (!report_modified_aggregates_ && field_path.back().field == NULL) {
  1681. if (field_path.back().unknown_field_type == UnknownField::TYPE_GROUP) {
  1682. // Any changes to the subfields have already been printed.
  1683. return;
  1684. }
  1685. } else if (!report_modified_aggregates_) {
  1686. if (field_path.back().field->cpp_type() ==
  1687. FieldDescriptor::CPPTYPE_MESSAGE) {
  1688. // Any changes to the subfields have already been printed.
  1689. return;
  1690. }
  1691. }
  1692. printer_->Print("modified: ");
  1693. PrintPath(field_path, true, message1);
  1694. if (CheckPathChanged(field_path)) {
  1695. printer_->Print(" -> ");
  1696. PrintPath(field_path, false, message2);
  1697. }
  1698. printer_->Print(": ");
  1699. PrintValue(message1, field_path, true);
  1700. printer_->Print(" -> ");
  1701. PrintValue(message2, field_path, false);
  1702. printer_->Print("\n"); // Print for newlines.
  1703. }
  1704. void MessageDifferencer::StreamReporter::ReportMoved(
  1705. const Message& message1, const Message& message2,
  1706. const std::vector<SpecificField>& field_path) {
  1707. printer_->Print("moved: ");
  1708. PrintPath(field_path, true, message1);
  1709. printer_->Print(" -> ");
  1710. PrintPath(field_path, false, message2);
  1711. printer_->Print(" : ");
  1712. PrintValue(message1, field_path, true);
  1713. printer_->Print("\n"); // Print for newlines.
  1714. }
  1715. void MessageDifferencer::StreamReporter::ReportMatched(
  1716. const Message& message1, const Message& message2,
  1717. const std::vector<SpecificField>& field_path) {
  1718. printer_->Print("matched: ");
  1719. PrintPath(field_path, true, message1);
  1720. if (CheckPathChanged(field_path)) {
  1721. printer_->Print(" -> ");
  1722. PrintPath(field_path, false, message2);
  1723. }
  1724. printer_->Print(" : ");
  1725. PrintValue(message1, field_path, true);
  1726. printer_->Print("\n"); // Print for newlines.
  1727. }
  1728. void MessageDifferencer::StreamReporter::ReportIgnored(
  1729. const Message& message1, const Message& message2,
  1730. const std::vector<SpecificField>& field_path) {
  1731. printer_->Print("ignored: ");
  1732. PrintPath(field_path, true, message1);
  1733. if (CheckPathChanged(field_path)) {
  1734. printer_->Print(" -> ");
  1735. PrintPath(field_path, false, message2);
  1736. }
  1737. printer_->Print("\n"); // Print for newlines.
  1738. }
  1739. void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored(
  1740. const Message& message1, const Message& message2,
  1741. const std::vector<SpecificField>& field_path) {
  1742. printer_->Print("ignored: ");
  1743. PrintPath(field_path, true, message1);
  1744. if (CheckPathChanged(field_path)) {
  1745. printer_->Print(" -> ");
  1746. PrintPath(field_path, false, message2);
  1747. }
  1748. printer_->Print("\n"); // Print for newlines.
  1749. }
  1750. MessageDifferencer::MapKeyComparator*
  1751. MessageDifferencer::CreateMultipleFieldsMapKeyComparator(
  1752. const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) {
  1753. return new MultipleFieldsMapKeyComparator(this, key_field_paths);
  1754. }
  1755. } // namespace util
  1756. } // namespace protobuf
  1757. } // namespace google