message_differencer.cc 64 KB

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