31 #include <google/protobuf/util/field_mask_util.h>
35 #include <google/protobuf/message.h>
36 #include <google/protobuf/stubs/strutil.h>
37 #include <google/protobuf/stubs/map_util.h>
40 #include <google/protobuf/port_def.inc>
54 std::vector<std::string> paths =
Split(
str,
",");
56 if (
path.empty())
continue;
64 bool after_underscore =
false;
65 for (
char input_char :
input) {
66 if (input_char >=
'A' && input_char <=
'Z') {
70 if (after_underscore) {
71 if (input_char >=
'a' && input_char <=
'z') {
72 output->push_back(input_char +
'A' -
'a');
73 after_underscore =
false;
78 }
else if (input_char ==
'_') {
79 after_underscore =
true;
81 output->push_back(input_char);
84 if (after_underscore) {
94 for (
const char c :
input) {
99 if (c >=
'A' && c <=
'Z') {
101 output->push_back(c +
'a' -
'A');
120 out->append(camelcase_path);
127 std::vector<std::string> paths =
Split(
str,
",");
129 if (
path.empty())
continue;
134 out->add_paths(snakecase_path);
141 std::vector<const FieldDescriptor*>* field_descriptors) {
142 if (field_descriptors !=
nullptr) {
143 field_descriptors->clear();
145 std::vector<std::string> parts =
Split(
path,
".");
151 if (
field ==
nullptr) {
154 if (field_descriptors !=
nullptr) {
155 field_descriptors->push_back(
field);
157 if (!
field->is_repeated() &&
185 class FieldMaskTree {
190 void MergeFromFieldMask(
const FieldMask& mask);
214 void MergeMessage(
const Message& source,
218 if (
root_.children.empty()) {
230 if (
root_.children.empty()) {
240 if (
root_.children.empty()) {
250 ~
Node() { ClearChildren(); }
252 void ClearChildren() {
276 void MergeMessage(
const Node* node,
const Message& source,
295 FieldMaskTree::FieldMaskTree() {}
297 FieldMaskTree::~FieldMaskTree() {}
299 void FieldMaskTree::MergeFromFieldMask(
const FieldMask& mask) {
301 AddPath(mask.
paths(i));
305 void FieldMaskTree::MergeToFieldMask(
FieldMask* mask) {
306 MergeToFieldMask(
"", &
root_, mask);
311 if (node->children.empty()) {
319 for (std::map<std::string, Node*>::const_iterator
it = node->children.begin();
320 it != node->children.end(); ++
it) {
323 MergeToFieldMask(current_path,
it->second,
out);
328 std::vector<std::string> parts =
Split(
path,
".");
332 bool new_branch =
false;
335 if (!new_branch && node != &
root_ && node->children.empty()) {
341 Node*&
child = node->children[node_name];
348 if (!node->children.empty()) {
349 node->ClearChildren();
355 if (
root_.children.empty()) {
361 std::vector<std::string> parts =
Split(
path,
".");
365 std::vector<Node*> nodes(parts.size());
368 Node* new_branch_node =
nullptr;
369 for (
int i = 0;
i < parts.size(); ++
i) {
372 current_descriptor->FindFieldByName(parts[i]);
373 if (field_descriptor ==
nullptr ||
375 i != parts.size() - 1)) {
377 if (new_branch_node !=
nullptr) {
379 new_branch_node->ClearChildren();
384 if (node->children.empty()) {
385 if (new_branch_node ==
nullptr) {
386 new_branch_node = node;
388 for (
int j = 0;
j < current_descriptor->field_count(); ++
j) {
389 node->children[current_descriptor->field(j)->name()] =
new Node();
393 node = node->children[parts[
i]];
395 current_descriptor = field_descriptor->message_type();
403 for (
int i = parts.size() - 1; i >= 0; i--) {
404 delete nodes[
i]->children[parts[
i]];
405 nodes[
i]->children.erase(parts[i]);
413 std::vector<std::string> parts =
Split(
path,
".");
419 if (node->children.empty()) {
420 if (node != &
root_) {
434 MergeLeafNodesToTree(
path, node,
out);
438 const Node* node, FieldMaskTree*
out) {
439 if (node->children.empty()) {
442 for (std::map<std::string, Node*>::const_iterator
it = node->children.begin();
443 it != node->children.end(); ++
it) {
446 MergeLeafNodesToTree(current_path,
it->second,
out);
450 void FieldMaskTree::MergeMessage(
const Node* node,
const Message& source,
454 const Reflection* source_reflection = source.GetReflection();
455 const Reflection* destination_reflection = destination->GetReflection();
457 for (std::map<std::string, Node*>::const_iterator
it = node->children.begin();
458 it != node->children.end(); ++
it) {
463 GOOGLE_LOG(
ERROR) <<
"Cannot find field \"" << field_name <<
"\" in message "
467 if (!
child->children.empty()) {
469 if (
field->is_repeated() ||
473 <<
" is not a singular message field and cannot "
474 <<
"have sub-fields.";
478 destination_reflection->MutableMessage(destination,
field));
481 if (!
field->is_repeated()) {
482 switch (
field->cpp_type()) {
483 #define COPY_VALUE(TYPE, Name) \
484 case FieldDescriptor::CPPTYPE_##TYPE: { \
485 if (source_reflection->HasField(source, field)) { \
486 destination_reflection->Set##Name( \
487 destination, field, source_reflection->Get##Name(source, field)); \
489 destination_reflection->ClearField(destination, field); \
504 if (
options.replace_message_fields()) {
505 destination_reflection->ClearField(destination,
field);
507 if (source_reflection->HasField(source,
field)) {
508 destination_reflection->MutableMessage(destination,
field)
509 ->MergeFrom(source_reflection->GetMessage(source,
field));
515 if (
options.replace_repeated_fields()) {
516 destination_reflection->ClearField(destination,
field);
518 switch (
field->cpp_type()) {
519 #define COPY_REPEATED_VALUE(TYPE, Name) \
520 case FieldDescriptor::CPPTYPE_##TYPE: { \
521 int size = source_reflection->FieldSize(source, field); \
522 for (int i = 0; i < size; ++i) { \
523 destination_reflection->Add##Name( \
524 destination, field, \
525 source_reflection->GetRepeated##Name(source, field, i)); \
538 #undef COPY_REPEATED_VALUE
540 int size = source_reflection->FieldSize(source,
field);
541 for (
int i = 0;
i <
size; ++
i) {
542 destination_reflection->AddMessage(destination,
field)
544 source_reflection->GetRepeatedMessage(source,
field, i));
553 void FieldMaskTree::AddRequiredFieldPath(
Node* node,
558 if (
field->is_required()) {
560 Node*&
child = node->children[node_name];
561 if (
child ==
nullptr) {
564 }
else if (
child->children.empty()) {
571 AddRequiredFieldPath(
child,
field->message_type());
574 std::map<std::string, Node*>::const_iterator
it =
575 node->children.find(
field->name());
576 if (
it != node->children.end()) {
580 if (!
child->children.empty()) {
581 AddRequiredFieldPath(
child,
field->message_type());
590 const Reflection* reflection =
message->GetReflection();
593 bool modified =
false;
596 std::map<std::string, Node*>::const_iterator
it =
597 node->children.find(
field->name());
598 if (
it == node->children.end()) {
599 if (
field->is_repeated()) {
613 bool nestedMessageChanged =
615 modified = nestedMessageChanged || modified;
627 tree.MergeFromFieldMask(mask);
629 tree.MergeToFieldMask(
out);
635 tree.MergeFromFieldMask(mask1);
636 tree.MergeFromFieldMask(mask2);
638 tree.MergeToFieldMask(
out);
643 FieldMaskTree tree, intersection;
644 tree.MergeFromFieldMask(mask1);
646 tree.IntersectPath(mask2.
paths(i), &intersection);
649 intersection.MergeToFieldMask(
out);
655 if (mask1.
paths().empty()) {
660 tree.MergeFromFieldMask(mask1);
665 tree.MergeToFieldMask(
out);
672 if (
path == mask_path) {
674 }
else if (mask_path.length() <
path.length()) {
676 if (
path.substr(0, mask_path.length() + 1).compare(mask_path +
".") ==
688 GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
692 tree.MergeFromFieldMask(mask);
693 tree.MergeMessage(source,
options, destination);
700 tree.MergeFromFieldMask(mask);
709 tree.MergeFromFieldMask(mask);
712 if (
options.keep_required_fields()) {