field_mask_util.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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. #include <google/protobuf/util/field_mask_util.h>
  31. #include <google/protobuf/stubs/strutil.h>
  32. #include <google/protobuf/stubs/map_util.h>
  33. namespace google {
  34. namespace protobuf {
  35. namespace util {
  36. using google::protobuf::FieldMask;
  37. string FieldMaskUtil::ToString(const FieldMask& mask) {
  38. return Join(mask.paths(), ",");
  39. }
  40. void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) {
  41. out->Clear();
  42. std::vector<string> paths = Split(str, ",");
  43. for (int i = 0; i < paths.size(); ++i) {
  44. if (paths[i].empty()) continue;
  45. out->add_paths(paths[i]);
  46. }
  47. }
  48. bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, string* output) {
  49. output->clear();
  50. bool after_underscore = false;
  51. for (int i = 0; i < input.size(); ++i) {
  52. if (input[i] >= 'A' && input[i] <= 'Z') {
  53. // The field name must not contain uppercase letters.
  54. return false;
  55. }
  56. if (after_underscore) {
  57. if (input[i] >= 'a' && input[i] <= 'z') {
  58. output->push_back(input[i] + 'A' - 'a');
  59. after_underscore = false;
  60. } else {
  61. // The character after a "_" must be a lowercase letter.
  62. return false;
  63. }
  64. } else if (input[i] == '_') {
  65. after_underscore = true;
  66. } else {
  67. output->push_back(input[i]);
  68. }
  69. }
  70. if (after_underscore) {
  71. // Trailing "_".
  72. return false;
  73. }
  74. return true;
  75. }
  76. bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input, string* output) {
  77. output->clear();
  78. for (int i = 0; i < input.size(); ++i) {
  79. if (input[i] == '_') {
  80. // The field name must not contain "_"s.
  81. return false;
  82. }
  83. if (input[i] >= 'A' && input[i] <= 'Z') {
  84. output->push_back('_');
  85. output->push_back(input[i] + 'a' - 'A');
  86. } else {
  87. output->push_back(input[i]);
  88. }
  89. }
  90. return true;
  91. }
  92. bool FieldMaskUtil::ToJsonString(const FieldMask& mask, string* out) {
  93. out->clear();
  94. for (int i = 0; i < mask.paths_size(); ++i) {
  95. const string& path = mask.paths(i);
  96. string camelcase_path;
  97. if (!SnakeCaseToCamelCase(path, &camelcase_path)) {
  98. return false;
  99. }
  100. if (i > 0) {
  101. out->push_back(',');
  102. }
  103. out->append(camelcase_path);
  104. }
  105. return true;
  106. }
  107. bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) {
  108. out->Clear();
  109. std::vector<string> paths = Split(str, ",");
  110. for (int i = 0; i < paths.size(); ++i) {
  111. if (paths[i].empty()) continue;
  112. string snakecase_path;
  113. if (!CamelCaseToSnakeCase(paths[i], &snakecase_path)) {
  114. return false;
  115. }
  116. out->add_paths(snakecase_path);
  117. }
  118. return true;
  119. }
  120. bool FieldMaskUtil::GetFieldDescriptors(
  121. const Descriptor* descriptor, StringPiece path,
  122. std::vector<const FieldDescriptor*>* field_descriptors) {
  123. if (field_descriptors != nullptr) {
  124. field_descriptors->clear();
  125. }
  126. std::vector<string> parts = Split(path, ".");
  127. for (int i = 0; i < parts.size(); ++i) {
  128. const string& field_name = parts[i];
  129. if (descriptor == nullptr) {
  130. return false;
  131. }
  132. const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
  133. if (field == nullptr) {
  134. return false;
  135. }
  136. if (field_descriptors != nullptr) {
  137. field_descriptors->push_back(field);
  138. }
  139. if (!field->is_repeated() &&
  140. field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  141. descriptor = field->message_type();
  142. } else {
  143. descriptor = nullptr;
  144. }
  145. }
  146. return true;
  147. }
  148. void FieldMaskUtil::InternalGetFieldMaskForAllFields(
  149. const Descriptor* descriptor, FieldMask* out) {
  150. for (int i = 0; i < descriptor->field_count(); ++i) {
  151. out->add_paths(descriptor->field(i)->name());
  152. }
  153. }
  154. namespace {
  155. // A FieldMaskTree represents a FieldMask in a tree structure. For example,
  156. // given a FieldMask "foo.bar,foo.baz,bar.baz", the FieldMaskTree will be:
  157. //
  158. // [root] -+- foo -+- bar
  159. // | |
  160. // | +- baz
  161. // |
  162. // +- bar --- baz
  163. //
  164. // In the tree, each leaf node represents a field path.
  165. class FieldMaskTree {
  166. public:
  167. FieldMaskTree();
  168. ~FieldMaskTree();
  169. void MergeFromFieldMask(const FieldMask& mask);
  170. void MergeToFieldMask(FieldMask* mask);
  171. // Add a field path into the tree. In a FieldMask, each field path matches
  172. // the specified field and also all its sub-fields. If the field path to
  173. // add is a sub-path of an existing field path in the tree (i.e., a leaf
  174. // node), it means the tree already matches the given path so nothing will
  175. // be added to the tree. If the path matches an existing non-leaf node in the
  176. // tree, that non-leaf node will be turned into a leaf node with all its
  177. // children removed because the path matches all the node's children.
  178. void AddPath(const string& path);
  179. // Remove a path from the tree.
  180. // If the path is a sub-path of an existing field path in the tree, it means
  181. // we need remove the existing fied path and add all sub-paths except
  182. // specified path. If the path matches an existing node in the tree, this node
  183. // will be moved.
  184. void RemovePath(const string& path, const Descriptor* descriptor);
  185. // Calculate the intersection part of a field path with this tree and add
  186. // the intersection field path into out.
  187. void IntersectPath(const string& path, FieldMaskTree* out);
  188. // Merge all fields specified by this tree from one message to another.
  189. void MergeMessage(const Message& source,
  190. const FieldMaskUtil::MergeOptions& options,
  191. Message* destination) {
  192. // Do nothing if the tree is empty.
  193. if (root_.children.empty()) {
  194. return;
  195. }
  196. MergeMessage(&root_, source, options, destination);
  197. }
  198. // Add required field path of the message to this tree based on current tree
  199. // structure. If a message is present in the tree, add the path of its
  200. // required field to the tree. This is to make sure that after trimming a
  201. // message with required fields are set, check IsInitialized() will not fail.
  202. void AddRequiredFieldPath(const Descriptor* descriptor) {
  203. // Do nothing if the tree is empty.
  204. if (root_.children.empty()) {
  205. return;
  206. }
  207. AddRequiredFieldPath(&root_, descriptor);
  208. }
  209. // Trims all fields not specified by this tree from the given message.
  210. void TrimMessage(Message* message) {
  211. // Do nothing if the tree is empty.
  212. if (root_.children.empty()) {
  213. return;
  214. }
  215. TrimMessage(&root_, message);
  216. }
  217. private:
  218. struct Node {
  219. Node() {}
  220. ~Node() { ClearChildren(); }
  221. void ClearChildren() {
  222. for (std::map<string, Node*>::iterator it = children.begin();
  223. it != children.end(); ++it) {
  224. delete it->second;
  225. }
  226. children.clear();
  227. }
  228. std::map<string, Node*> children;
  229. private:
  230. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
  231. };
  232. // Merge a sub-tree to mask. This method adds the field paths represented
  233. // by all leaf nodes descended from "node" to mask.
  234. void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
  235. // Merge all leaf nodes of a sub-tree to another tree.
  236. void MergeLeafNodesToTree(const string& prefix, const Node* node,
  237. FieldMaskTree* out);
  238. // Merge all fields specified by a sub-tree from one message to another.
  239. void MergeMessage(const Node* node, const Message& source,
  240. const FieldMaskUtil::MergeOptions& options,
  241. Message* destination);
  242. // Add required field path of the message to this tree based on current tree
  243. // structure. If a message is present in the tree, add the path of its
  244. // required field to the tree. This is to make sure that after trimming a
  245. // message with required fields are set, check IsInitialized() will not fail.
  246. void AddRequiredFieldPath(Node* node, const Descriptor* descriptor);
  247. // Trims all fields not specified by this sub-tree from the given message.
  248. void TrimMessage(const Node* node, Message* message);
  249. Node root_;
  250. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
  251. };
  252. FieldMaskTree::FieldMaskTree() {}
  253. FieldMaskTree::~FieldMaskTree() {}
  254. void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
  255. for (int i = 0; i < mask.paths_size(); ++i) {
  256. AddPath(mask.paths(i));
  257. }
  258. }
  259. void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
  260. MergeToFieldMask("", &root_, mask);
  261. }
  262. void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
  263. FieldMask* out) {
  264. if (node->children.empty()) {
  265. if (prefix.empty()) {
  266. // This is the root node.
  267. return;
  268. }
  269. out->add_paths(prefix);
  270. return;
  271. }
  272. for (std::map<string, Node*>::const_iterator it = node->children.begin();
  273. it != node->children.end(); ++it) {
  274. string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
  275. MergeToFieldMask(current_path, it->second, out);
  276. }
  277. }
  278. void FieldMaskTree::AddPath(const string& path) {
  279. std::vector<string> parts = Split(path, ".");
  280. if (parts.empty()) {
  281. return;
  282. }
  283. bool new_branch = false;
  284. Node* node = &root_;
  285. for (int i = 0; i < parts.size(); ++i) {
  286. if (!new_branch && node != &root_ && node->children.empty()) {
  287. // Path matches an existing leaf node. This means the path is already
  288. // coverred by this tree (for example, adding "foo.bar.baz" to a tree
  289. // which already contains "foo.bar").
  290. return;
  291. }
  292. const string& node_name = parts[i];
  293. Node*& child = node->children[node_name];
  294. if (child == NULL) {
  295. new_branch = true;
  296. child = new Node();
  297. }
  298. node = child;
  299. }
  300. if (!node->children.empty()) {
  301. node->ClearChildren();
  302. }
  303. }
  304. void FieldMaskTree::RemovePath(const string& path,
  305. const Descriptor* descriptor) {
  306. if (root_.children.empty()) {
  307. // Nothing to be removed from an empty tree. We shortcut it here so an empty
  308. // tree won't be interpreted as a field mask containing all fields by the
  309. // code below.
  310. return;
  311. }
  312. std::vector<string> parts = Split(path, ".");
  313. if (parts.empty()) {
  314. return;
  315. }
  316. std::vector<Node*> nodes(parts.size());
  317. Node* node = &root_;
  318. const Descriptor* current_descriptor = descriptor;
  319. Node* new_branch_node = nullptr;
  320. for (int i = 0; i < parts.size(); ++i) {
  321. nodes[i] = node;
  322. const FieldDescriptor* field_descriptor =
  323. current_descriptor->FindFieldByName(parts[i]);
  324. if (field_descriptor == nullptr ||
  325. (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
  326. i != parts.size() - 1)) {
  327. // Invalid path.
  328. if (new_branch_node != nullptr) {
  329. // If add any new nodes, cleanup.
  330. new_branch_node->ClearChildren();
  331. }
  332. return;
  333. }
  334. if (node->children.empty()) {
  335. if (new_branch_node == nullptr) {
  336. new_branch_node = node;
  337. }
  338. for (int i = 0; i < current_descriptor->field_count(); ++i) {
  339. node->children[current_descriptor->field(i)->name()] = new Node();
  340. }
  341. }
  342. if (ContainsKey(node->children, parts[i])) {
  343. node = node->children[parts[i]];
  344. if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  345. current_descriptor = field_descriptor->message_type();
  346. }
  347. } else {
  348. // Path does not exist.
  349. return;
  350. }
  351. }
  352. // Remove path.
  353. for (int i = parts.size() - 1; i >= 0; i--) {
  354. delete nodes[i]->children[parts[i]];
  355. nodes[i]->children.erase(parts[i]);
  356. if (!nodes[i]->children.empty()) {
  357. break;
  358. }
  359. }
  360. }
  361. void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
  362. std::vector<string> parts = Split(path, ".");
  363. if (parts.empty()) {
  364. return;
  365. }
  366. const Node* node = &root_;
  367. for (int i = 0; i < parts.size(); ++i) {
  368. if (node->children.empty()) {
  369. if (node != &root_) {
  370. out->AddPath(path);
  371. }
  372. return;
  373. }
  374. const string& node_name = parts[i];
  375. const Node* result = FindPtrOrNull(node->children, node_name);
  376. if (result == NULL) {
  377. // No intersection found.
  378. return;
  379. }
  380. node = result;
  381. }
  382. // Now we found a matching node with the given path. Add all leaf nodes
  383. // to out.
  384. MergeLeafNodesToTree(path, node, out);
  385. }
  386. void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
  387. FieldMaskTree* out) {
  388. if (node->children.empty()) {
  389. out->AddPath(prefix);
  390. }
  391. for (std::map<string, Node*>::const_iterator it = node->children.begin();
  392. it != node->children.end(); ++it) {
  393. string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
  394. MergeLeafNodesToTree(current_path, it->second, out);
  395. }
  396. }
  397. void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
  398. const FieldMaskUtil::MergeOptions& options,
  399. Message* destination) {
  400. GOOGLE_DCHECK(!node->children.empty());
  401. const Reflection* source_reflection = source.GetReflection();
  402. const Reflection* destination_reflection = destination->GetReflection();
  403. const Descriptor* descriptor = source.GetDescriptor();
  404. for (std::map<string, Node*>::const_iterator it = node->children.begin();
  405. it != node->children.end(); ++it) {
  406. const string& field_name = it->first;
  407. const Node* child = it->second;
  408. const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
  409. if (field == NULL) {
  410. GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message "
  411. << descriptor->full_name();
  412. continue;
  413. }
  414. if (!child->children.empty()) {
  415. // Sub-paths are only allowed for singular message fields.
  416. if (field->is_repeated() ||
  417. field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
  418. GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
  419. << descriptor->full_name()
  420. << " is not a singular message field and cannot "
  421. << "have sub-fields.";
  422. continue;
  423. }
  424. MergeMessage(child, source_reflection->GetMessage(source, field), options,
  425. destination_reflection->MutableMessage(destination, field));
  426. continue;
  427. }
  428. if (!field->is_repeated()) {
  429. switch (field->cpp_type()) {
  430. #define COPY_VALUE(TYPE, Name) \
  431. case FieldDescriptor::CPPTYPE_##TYPE: { \
  432. if (source_reflection->HasField(source, field)) { \
  433. destination_reflection->Set##Name( \
  434. destination, field, source_reflection->Get##Name(source, field)); \
  435. } else { \
  436. destination_reflection->ClearField(destination, field); \
  437. } \
  438. break; \
  439. }
  440. COPY_VALUE(BOOL, Bool)
  441. COPY_VALUE(INT32, Int32)
  442. COPY_VALUE(INT64, Int64)
  443. COPY_VALUE(UINT32, UInt32)
  444. COPY_VALUE(UINT64, UInt64)
  445. COPY_VALUE(FLOAT, Float)
  446. COPY_VALUE(DOUBLE, Double)
  447. COPY_VALUE(ENUM, Enum)
  448. COPY_VALUE(STRING, String)
  449. #undef COPY_VALUE
  450. case FieldDescriptor::CPPTYPE_MESSAGE: {
  451. if (options.replace_message_fields()) {
  452. destination_reflection->ClearField(destination, field);
  453. }
  454. if (source_reflection->HasField(source, field)) {
  455. destination_reflection->MutableMessage(destination, field)
  456. ->MergeFrom(source_reflection->GetMessage(source, field));
  457. }
  458. break;
  459. }
  460. }
  461. } else {
  462. if (options.replace_repeated_fields()) {
  463. destination_reflection->ClearField(destination, field);
  464. }
  465. switch (field->cpp_type()) {
  466. #define COPY_REPEATED_VALUE(TYPE, Name) \
  467. case FieldDescriptor::CPPTYPE_##TYPE: { \
  468. int size = source_reflection->FieldSize(source, field); \
  469. for (int i = 0; i < size; ++i) { \
  470. destination_reflection->Add##Name( \
  471. destination, field, \
  472. source_reflection->GetRepeated##Name(source, field, i)); \
  473. } \
  474. break; \
  475. }
  476. COPY_REPEATED_VALUE(BOOL, Bool)
  477. COPY_REPEATED_VALUE(INT32, Int32)
  478. COPY_REPEATED_VALUE(INT64, Int64)
  479. COPY_REPEATED_VALUE(UINT32, UInt32)
  480. COPY_REPEATED_VALUE(UINT64, UInt64)
  481. COPY_REPEATED_VALUE(FLOAT, Float)
  482. COPY_REPEATED_VALUE(DOUBLE, Double)
  483. COPY_REPEATED_VALUE(ENUM, Enum)
  484. COPY_REPEATED_VALUE(STRING, String)
  485. #undef COPY_REPEATED_VALUE
  486. case FieldDescriptor::CPPTYPE_MESSAGE: {
  487. int size = source_reflection->FieldSize(source, field);
  488. for (int i = 0; i < size; ++i) {
  489. destination_reflection->AddMessage(destination, field)
  490. ->MergeFrom(
  491. source_reflection->GetRepeatedMessage(source, field, i));
  492. }
  493. break;
  494. }
  495. }
  496. }
  497. }
  498. }
  499. void FieldMaskTree::AddRequiredFieldPath(
  500. Node* node, const Descriptor* descriptor) {
  501. const int32 field_count = descriptor->field_count();
  502. for (int index = 0; index < field_count; ++index) {
  503. const FieldDescriptor* field = descriptor->field(index);
  504. if (field->is_required()) {
  505. const string& node_name = field->name();
  506. Node*& child = node->children[node_name];
  507. if (child == nullptr) {
  508. // Add required field path to the tree
  509. child = new Node();
  510. } else if (child->children.empty()){
  511. // If the required field is in the tree and does not have any children,
  512. // do nothing.
  513. continue;
  514. }
  515. // Add required field in the children to the tree if the field is message.
  516. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  517. AddRequiredFieldPath(child, field->message_type());
  518. }
  519. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  520. std::map<string, Node*>::const_iterator it =
  521. node->children.find(field->name());
  522. if (it != node->children.end()) {
  523. // Add required fields in the children to the
  524. // tree if the field is a message and present in the tree.
  525. Node* child = it->second;
  526. if (!child->children.empty()) {
  527. AddRequiredFieldPath(child, field->message_type());
  528. }
  529. }
  530. }
  531. }
  532. }
  533. void FieldMaskTree::TrimMessage(const Node* node, Message* message) {
  534. GOOGLE_DCHECK(!node->children.empty());
  535. const Reflection* reflection = message->GetReflection();
  536. const Descriptor* descriptor = message->GetDescriptor();
  537. const int32 field_count = descriptor->field_count();
  538. for (int index = 0; index < field_count; ++index) {
  539. const FieldDescriptor* field = descriptor->field(index);
  540. std::map<string, Node*>::const_iterator it =
  541. node->children.find(field->name());
  542. if (it == node->children.end()) {
  543. reflection->ClearField(message, field);
  544. } else {
  545. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  546. Node* child = it->second;
  547. if (!child->children.empty() && reflection->HasField(*message, field)) {
  548. TrimMessage(child, reflection->MutableMessage(message, field));
  549. }
  550. }
  551. }
  552. }
  553. }
  554. } // namespace
  555. void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
  556. FieldMaskTree tree;
  557. tree.MergeFromFieldMask(mask);
  558. out->Clear();
  559. tree.MergeToFieldMask(out);
  560. }
  561. void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
  562. FieldMask* out) {
  563. FieldMaskTree tree;
  564. tree.MergeFromFieldMask(mask1);
  565. tree.MergeFromFieldMask(mask2);
  566. out->Clear();
  567. tree.MergeToFieldMask(out);
  568. }
  569. void FieldMaskUtil::Intersect(const FieldMask& mask1, const FieldMask& mask2,
  570. FieldMask* out) {
  571. FieldMaskTree tree, intersection;
  572. tree.MergeFromFieldMask(mask1);
  573. for (int i = 0; i < mask2.paths_size(); ++i) {
  574. tree.IntersectPath(mask2.paths(i), &intersection);
  575. }
  576. out->Clear();
  577. intersection.MergeToFieldMask(out);
  578. }
  579. void FieldMaskUtil::InternalSubtract(const Descriptor* descriptor,
  580. const FieldMask& mask1,
  581. const FieldMask& mask2, FieldMask* out) {
  582. if (mask1.paths().empty()) {
  583. out->Clear();
  584. return;
  585. }
  586. FieldMaskTree tree;
  587. tree.MergeFromFieldMask(mask1);
  588. for (int i = 0; i < mask2.paths_size(); ++i) {
  589. tree.RemovePath(mask2.paths(i), descriptor);
  590. }
  591. out->Clear();
  592. tree.MergeToFieldMask(out);
  593. }
  594. bool FieldMaskUtil::IsPathInFieldMask(StringPiece path, const FieldMask& mask) {
  595. for (int i = 0; i < mask.paths_size(); ++i) {
  596. const string& mask_path = mask.paths(i);
  597. if (path == mask_path) {
  598. return true;
  599. } else if (mask_path.length() < path.length()) {
  600. // Also check whether mask.paths(i) is a prefix of path.
  601. if (path.substr(0, mask_path.length() + 1).compare(mask_path + ".") ==
  602. 0) {
  603. return true;
  604. }
  605. }
  606. }
  607. return false;
  608. }
  609. void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask,
  610. const MergeOptions& options,
  611. Message* destination) {
  612. GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
  613. // Build a FieldMaskTree and walk through the tree to merge all specified
  614. // fields.
  615. FieldMaskTree tree;
  616. tree.MergeFromFieldMask(mask);
  617. tree.MergeMessage(source, options, destination);
  618. }
  619. void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) {
  620. // Build a FieldMaskTree and walk through the tree to merge all specified
  621. // fields.
  622. FieldMaskTree tree;
  623. tree.MergeFromFieldMask(mask);
  624. tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
  625. }
  626. void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination,
  627. const TrimOptions& options) {
  628. // Build a FieldMaskTree and walk through the tree to merge all specified
  629. // fields.
  630. FieldMaskTree tree;
  631. tree.MergeFromFieldMask(mask);
  632. // If keep_required_fields is true, implicitely add required fields of
  633. // a message present in the tree to prevent from trimming.
  634. if (options.keep_required_fields()) {
  635. tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(destination->GetDescriptor()));
  636. }
  637. tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
  638. }
  639. } // namespace util
  640. } // namespace protobuf
  641. } // namespace google