37 #include <google/protobuf/port_def.inc>
51 std::vector<std::string> paths =
Split(
str,
",");
52 for (
int i = 0;
i < paths.size(); ++
i) {
53 if (paths[
i].empty())
continue;
61 bool after_underscore =
false;
62 for (
int i = 0;
i <
input.size(); ++
i) {
67 if (after_underscore) {
70 after_underscore =
false;
75 }
else if (
input[
i] ==
'_') {
76 after_underscore =
true;
81 if (after_underscore) {
91 for (
int i = 0;
i <
input.size(); ++
i) {
108 for (
int i = 0;
i <
mask.paths_size(); ++
i) {
117 out->append(camelcase_path);
124 std::vector<std::string> paths =
Split(
str,
",");
125 for (
int i = 0;
i < paths.size(); ++
i) {
126 if (paths[
i].empty())
continue;
138 std::vector<const FieldDescriptor*>* field_descriptors) {
139 if (field_descriptors !=
nullptr) {
140 field_descriptors->clear();
142 std::vector<std::string> parts =
Split(
path,
".");
143 for (
int i = 0;
i < parts.size(); ++
i) {
149 if (
field ==
nullptr) {
152 if (field_descriptors !=
nullptr) {
153 field_descriptors->push_back(
field);
155 if (!
field->is_repeated() &&
183 class FieldMaskTree {
216 if (
root_.children.empty()) {
228 if (
root_.children.empty()) {
236 bool TrimMessage(Message*
message) {
238 if (
root_.children.empty()) {
248 ~Node() { ClearChildren(); }
250 void ClearChildren() {
251 for (std::map<std::string, Node*>::iterator
it =
children.begin();
274 void MergeMessage(
const Node* node,
const Message&
source,
276 Message* destination);
286 bool TrimMessage(
const Node* node, Message*
message);
293 FieldMaskTree::FieldMaskTree() {}
295 FieldMaskTree::~FieldMaskTree() {}
297 void FieldMaskTree::MergeFromFieldMask(
const FieldMask&
mask) {
298 for (
int i = 0;
i <
mask.paths_size(); ++
i) {
299 AddPath(
mask.paths(
i));
309 if (node->children.empty()) {
317 for (std::map<std::string, Node*>::const_iterator
it = node->children.begin();
318 it != node->children.end(); ++
it) {
321 MergeToFieldMask(current_path,
it->second, out);
326 std::vector<std::string> parts =
Split(
path,
".");
330 bool new_branch =
false;
332 for (
int i = 0;
i < parts.size(); ++
i) {
333 if (!new_branch && node != &
root_ && node->children.empty()) {
340 Node*&
child = node->children[node_name];
347 if (!node->children.empty()) {
348 node->ClearChildren();
354 if (
root_.children.empty()) {
360 std::vector<std::string> parts =
Split(
path,
".");
364 std::vector<Node*> nodes(parts.size());
367 Node* new_branch_node =
nullptr;
368 for (
int i = 0;
i < parts.size(); ++
i) {
371 current_descriptor->FindFieldByName(parts[
i]);
372 if (field_descriptor ==
nullptr ||
374 i != parts.size() - 1)) {
376 if (new_branch_node !=
nullptr) {
378 new_branch_node->ClearChildren();
383 if (node->children.empty()) {
384 if (new_branch_node ==
nullptr) {
385 new_branch_node = node;
387 for (
int i = 0;
i < current_descriptor->field_count(); ++
i) {
388 node->children[current_descriptor->field(
i)->name()] =
new Node();
392 node = node->children[parts[
i]];
394 current_descriptor = field_descriptor->message_type();
402 for (
int i = parts.size() - 1;
i >= 0;
i--) {
403 delete nodes[
i]->children[parts[
i]];
404 nodes[
i]->children.erase(parts[
i]);
411 void FieldMaskTree::IntersectPath(
const std::string&
path, FieldMaskTree* out) {
412 std::vector<std::string> parts =
Split(
path,
".");
416 const Node* node = &
root_;
417 for (
int i = 0;
i < parts.size(); ++
i) {
418 if (node->children.empty()) {
419 if (node != &
root_) {
425 const Node* result =
FindPtrOrNull(node->children, node_name);
426 if (result ==
NULL) {
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,
452 Message* destination) {
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) {
460 const Node*
child =
it->second;
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);
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
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());
588 bool FieldMaskTree::TrimMessage(
const Node* node, Message*
message) {
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;
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);
670 for (
int i = 0;
i <
mask.paths_size(); ++
i) {
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 +
".") ==
712 if (
options.keep_required_fields()) {