Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/field_mask_util.cc

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 27 matching lines...) Expand all
38 namespace util { 38 namespace util {
39 39
40 using google::protobuf::FieldMask; 40 using google::protobuf::FieldMask;
41 41
42 string FieldMaskUtil::ToString(const FieldMask& mask) { 42 string FieldMaskUtil::ToString(const FieldMask& mask) {
43 return Join(mask.paths(), ","); 43 return Join(mask.paths(), ",");
44 } 44 }
45 45
46 void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) { 46 void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) {
47 out->Clear(); 47 out->Clear();
48 std::vector<string> paths = Split(str, ","); 48 vector<string> paths = Split(str, ",");
49 for (int i = 0; i < paths.size(); ++i) { 49 for (int i = 0; i < paths.size(); ++i) {
50 if (paths[i].empty()) continue; 50 if (paths[i].empty()) continue;
51 out->add_paths(paths[i]); 51 out->add_paths(paths[i]);
52 } 52 }
53 } 53 }
54 54
55 bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, string* output) { 55 bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, string* output) {
56 output->clear(); 56 output->clear();
57 bool after_underscore = false; 57 bool after_underscore = false;
58 for (int i = 0; i < input.size(); ++i) { 58 for (int i = 0; i < input.size(); ++i) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 if (i > 0) { 109 if (i > 0) {
110 out->push_back(','); 110 out->push_back(',');
111 } 111 }
112 out->append(camelcase_path); 112 out->append(camelcase_path);
113 } 113 }
114 return true; 114 return true;
115 } 115 }
116 116
117 bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) { 117 bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) {
118 out->Clear(); 118 out->Clear();
119 std::vector<string> paths = Split(str, ","); 119 vector<string> paths = Split(str, ",");
120 for (int i = 0; i < paths.size(); ++i) { 120 for (int i = 0; i < paths.size(); ++i) {
121 if (paths[i].empty()) continue; 121 if (paths[i].empty()) continue;
122 string snakecase_path; 122 string snakecase_path;
123 if (!CamelCaseToSnakeCase(paths[i], &snakecase_path)) { 123 if (!CamelCaseToSnakeCase(paths[i], &snakecase_path)) {
124 return false; 124 return false;
125 } 125 }
126 out->add_paths(snakecase_path); 126 out->add_paths(snakecase_path);
127 } 127 }
128 return true; 128 return true;
129 } 129 }
130 130
131 bool FieldMaskUtil::GetFieldDescriptors( 131 bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor,
132 const Descriptor* descriptor, StringPiece path, 132 StringPiece path) {
133 std::vector<const FieldDescriptor*>* field_descriptors) { 133 vector<string> parts = Split(path, ".");
134 if (field_descriptors != NULL) {
135 field_descriptors->clear();
136 }
137 std::vector<string> parts = Split(path, ".");
138 for (int i = 0; i < parts.size(); ++i) { 134 for (int i = 0; i < parts.size(); ++i) {
139 const string& field_name = parts[i]; 135 const string& field_name = parts[i];
140 if (descriptor == NULL) { 136 if (descriptor == NULL) {
141 return false; 137 return false;
142 } 138 }
143 const FieldDescriptor* field = descriptor->FindFieldByName(field_name); 139 const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
144 if (field == NULL) { 140 if (field == NULL) {
145 return false; 141 return false;
146 } 142 }
147 if (field_descriptors != NULL) {
148 field_descriptors->push_back(field);
149 }
150 if (!field->is_repeated() && 143 if (!field->is_repeated() &&
151 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 144 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
152 descriptor = field->message_type(); 145 descriptor = field->message_type();
153 } else { 146 } else {
154 descriptor = NULL; 147 descriptor = NULL;
155 } 148 }
156 } 149 }
157 return true; 150 return true;
158 } 151 }
159 152
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 void MergeMessage(const Message& source, 193 void MergeMessage(const Message& source,
201 const FieldMaskUtil::MergeOptions& options, 194 const FieldMaskUtil::MergeOptions& options,
202 Message* destination) { 195 Message* destination) {
203 // Do nothing if the tree is empty. 196 // Do nothing if the tree is empty.
204 if (root_.children.empty()) { 197 if (root_.children.empty()) {
205 return; 198 return;
206 } 199 }
207 MergeMessage(&root_, source, options, destination); 200 MergeMessage(&root_, source, options, destination);
208 } 201 }
209 202
210 // Trims all fields not specified by this tree from the given message.
211 void TrimMessage(Message* message) {
212 // Do nothing if the tree is empty.
213 if (root_.children.empty()) {
214 return;
215 }
216 TrimMessage(&root_, message);
217 }
218
219 private: 203 private:
220 struct Node { 204 struct Node {
221 Node() {} 205 Node() {}
222 206
223 ~Node() { ClearChildren(); } 207 ~Node() { ClearChildren(); }
224 208
225 void ClearChildren() { 209 void ClearChildren() {
226 for (std::map<string, Node*>::iterator it = children.begin(); 210 for (map<string, Node*>::iterator it = children.begin();
227 it != children.end(); ++it) { 211 it != children.end(); ++it) {
228 delete it->second; 212 delete it->second;
229 } 213 }
230 children.clear(); 214 children.clear();
231 } 215 }
232 216
233 std::map<string, Node*> children; 217 map<string, Node*> children;
234 218
235 private: 219 private:
236 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); 220 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
237 }; 221 };
238 222
239 // Merge a sub-tree to mask. This method adds the field paths represented 223 // Merge a sub-tree to mask. This method adds the field paths represented
240 // by all leaf nodes descended from "node" to mask. 224 // by all leaf nodes descended from "node" to mask.
241 void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out); 225 void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
242 226
243 // Merge all leaf nodes of a sub-tree to another tree. 227 // Merge all leaf nodes of a sub-tree to another tree.
244 void MergeLeafNodesToTree(const string& prefix, const Node* node, 228 void MergeLeafNodesToTree(const string& prefix, const Node* node,
245 FieldMaskTree* out); 229 FieldMaskTree* out);
246 230
247 // Merge all fields specified by a sub-tree from one message to another. 231 // Merge all fields specified by a sub-tree from one message to another.
248 void MergeMessage(const Node* node, const Message& source, 232 void MergeMessage(const Node* node, const Message& source,
249 const FieldMaskUtil::MergeOptions& options, 233 const FieldMaskUtil::MergeOptions& options,
250 Message* destination); 234 Message* destination);
251 235
252 // Trims all fields not specified by this sub-tree from the given message.
253 void TrimMessage(const Node* node, Message* message);
254
255 Node root_; 236 Node root_;
256 237
257 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree); 238 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
258 }; 239 };
259 240
260 FieldMaskTree::FieldMaskTree() {} 241 FieldMaskTree::FieldMaskTree() {}
261 242
262 FieldMaskTree::~FieldMaskTree() {} 243 FieldMaskTree::~FieldMaskTree() {}
263 244
264 void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) { 245 void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
265 for (int i = 0; i < mask.paths_size(); ++i) { 246 for (int i = 0; i < mask.paths_size(); ++i) {
266 AddPath(mask.paths(i)); 247 AddPath(mask.paths(i));
267 } 248 }
268 } 249 }
269 250
270 void FieldMaskTree::MergeToFieldMask(FieldMask* mask) { 251 void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
271 MergeToFieldMask("", &root_, mask); 252 MergeToFieldMask("", &root_, mask);
272 } 253 }
273 254
274 void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node, 255 void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
275 FieldMask* out) { 256 FieldMask* out) {
276 if (node->children.empty()) { 257 if (node->children.empty()) {
277 if (prefix.empty()) { 258 if (prefix.empty()) {
278 // This is the root node. 259 // This is the root node.
279 return; 260 return;
280 } 261 }
281 out->add_paths(prefix); 262 out->add_paths(prefix);
282 return; 263 return;
283 } 264 }
284 for (std::map<string, Node*>::const_iterator it = node->children.begin(); 265 for (map<string, Node*>::const_iterator it = node->children.begin();
285 it != node->children.end(); ++it) { 266 it != node->children.end(); ++it) {
286 string current_path = prefix.empty() ? it->first : prefix + "." + it->first; 267 string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
287 MergeToFieldMask(current_path, it->second, out); 268 MergeToFieldMask(current_path, it->second, out);
288 } 269 }
289 } 270 }
290 271
291 void FieldMaskTree::AddPath(const string& path) { 272 void FieldMaskTree::AddPath(const string& path) {
292 std::vector<string> parts = Split(path, "."); 273 vector<string> parts = Split(path, ".");
293 if (parts.empty()) { 274 if (parts.empty()) {
294 return; 275 return;
295 } 276 }
296 bool new_branch = false; 277 bool new_branch = false;
297 Node* node = &root_; 278 Node* node = &root_;
298 for (int i = 0; i < parts.size(); ++i) { 279 for (int i = 0; i < parts.size(); ++i) {
299 if (!new_branch && node != &root_ && node->children.empty()) { 280 if (!new_branch && node != &root_ && node->children.empty()) {
300 // Path matches an existing leaf node. This means the path is already 281 // Path matches an existing leaf node. This means the path is already
301 // coverred by this tree (for example, adding "foo.bar.baz" to a tree 282 // coverred by this tree (for example, adding "foo.bar.baz" to a tree
302 // which already contains "foo.bar"). 283 // which already contains "foo.bar").
303 return; 284 return;
304 } 285 }
305 const string& node_name = parts[i]; 286 const string& node_name = parts[i];
306 Node*& child = node->children[node_name]; 287 Node*& child = node->children[node_name];
307 if (child == NULL) { 288 if (child == NULL) {
308 new_branch = true; 289 new_branch = true;
309 child = new Node(); 290 child = new Node();
310 } 291 }
311 node = child; 292 node = child;
312 } 293 }
313 if (!node->children.empty()) { 294 if (!node->children.empty()) {
314 node->ClearChildren(); 295 node->ClearChildren();
315 } 296 }
316 } 297 }
317 298
318 void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) { 299 void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
319 std::vector<string> parts = Split(path, "."); 300 vector<string> parts = Split(path, ".");
320 if (parts.empty()) { 301 if (parts.empty()) {
321 return; 302 return;
322 } 303 }
323 const Node* node = &root_; 304 const Node* node = &root_;
324 for (int i = 0; i < parts.size(); ++i) { 305 for (int i = 0; i < parts.size(); ++i) {
325 if (node->children.empty()) { 306 if (node->children.empty()) {
326 if (node != &root_) { 307 if (node != &root_) {
327 out->AddPath(path); 308 out->AddPath(path);
328 } 309 }
329 return; 310 return;
330 } 311 }
331 const string& node_name = parts[i]; 312 const string& node_name = parts[i];
332 const Node* result = FindPtrOrNull(node->children, node_name); 313 const Node* result = FindPtrOrNull(node->children, node_name);
333 if (result == NULL) { 314 if (result == NULL) {
334 // No intersection found. 315 // No intersection found.
335 return; 316 return;
336 } 317 }
337 node = result; 318 node = result;
338 } 319 }
339 // Now we found a matching node with the given path. Add all leaf nodes 320 // Now we found a matching node with the given path. Add all leaf nodes
340 // to out. 321 // to out.
341 MergeLeafNodesToTree(path, node, out); 322 MergeLeafNodesToTree(path, node, out);
342 } 323 }
343 324
344 void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node, 325 void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
345 FieldMaskTree* out) { 326 FieldMaskTree* out) {
346 if (node->children.empty()) { 327 if (node->children.empty()) {
347 out->AddPath(prefix); 328 out->AddPath(prefix);
348 } 329 }
349 for (std::map<string, Node*>::const_iterator it = node->children.begin(); 330 for (map<string, Node*>::const_iterator it = node->children.begin();
350 it != node->children.end(); ++it) { 331 it != node->children.end(); ++it) {
351 string current_path = prefix.empty() ? it->first : prefix + "." + it->first; 332 string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
352 MergeLeafNodesToTree(current_path, it->second, out); 333 MergeLeafNodesToTree(current_path, it->second, out);
353 } 334 }
354 } 335 }
355 336
356 void FieldMaskTree::MergeMessage(const Node* node, const Message& source, 337 void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
357 const FieldMaskUtil::MergeOptions& options, 338 const FieldMaskUtil::MergeOptions& options,
358 Message* destination) { 339 Message* destination) {
359 GOOGLE_DCHECK(!node->children.empty()); 340 GOOGLE_DCHECK(!node->children.empty());
360 const Reflection* source_reflection = source.GetReflection(); 341 const Reflection* source_reflection = source.GetReflection();
361 const Reflection* destination_reflection = destination->GetReflection(); 342 const Reflection* destination_reflection = destination->GetReflection();
362 const Descriptor* descriptor = source.GetDescriptor(); 343 const Descriptor* descriptor = source.GetDescriptor();
363 for (std::map<string, Node*>::const_iterator it = node->children.begin(); 344 for (map<string, Node*>::const_iterator it = node->children.begin();
364 it != node->children.end(); ++it) { 345 it != node->children.end(); ++it) {
365 const string& field_name = it->first; 346 const string& field_name = it->first;
366 const Node* child = it->second; 347 const Node* child = it->second;
367 const FieldDescriptor* field = descriptor->FindFieldByName(field_name); 348 const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
368 if (field == NULL) { 349 if (field == NULL) {
369 GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in messag e " 350 GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in messag e "
370 << descriptor->full_name(); 351 << descriptor->full_name();
371 continue; 352 continue;
372 } 353 }
373 if (!child->children.empty()) { 354 if (!child->children.empty()) {
374 // Sub-paths are only allowed for singular message fields. 355 // Sub-paths are only allowed for singular message fields.
375 if (field->is_repeated() || 356 if (field->is_repeated() ||
376 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 357 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
377 GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message " 358 GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
378 << descriptor->full_name() 359 << descriptor->full_name()
379 << " is not a singular message field and cannot " 360 << " is not a singular message field and cannot "
380 << "have sub-fields."; 361 << "have sub-fields.";
381 continue; 362 continue;
382 } 363 }
383 MergeMessage(child, source_reflection->GetMessage(source, field), options, 364 MergeMessage(child, source_reflection->GetMessage(source, field), options,
384 destination_reflection->MutableMessage(destination, field)); 365 destination_reflection->MutableMessage(destination, field));
385 continue; 366 continue;
386 } 367 }
387 if (!field->is_repeated()) { 368 if (!field->is_repeated()) {
388 switch (field->cpp_type()) { 369 switch (field->cpp_type()) {
389 #define COPY_VALUE(TYPE, Name) \ 370 #define COPY_VALUE(TYPE, Name) \
390 case FieldDescriptor::CPPTYPE_##TYPE: { \ 371 case FieldDescriptor::CPPTYPE_##TYPE: { \
391 if (source_reflection->HasField(source, field)) { \ 372 destination_reflection->Set##Name( \
392 destination_reflection->Set##Name( \ 373 destination, field, source_reflection->Get##Name(source, field)); \
393 destination, field, source_reflection->Get##Name(source, field)); \ 374 break; \
394 } else { \
395 destination_reflection->ClearField(destination, field); \
396 } \
397 break; \
398 } 375 }
399 COPY_VALUE(BOOL, Bool) 376 COPY_VALUE(BOOL, Bool)
400 COPY_VALUE(INT32, Int32) 377 COPY_VALUE(INT32, Int32)
401 COPY_VALUE(INT64, Int64) 378 COPY_VALUE(INT64, Int64)
402 COPY_VALUE(UINT32, UInt32) 379 COPY_VALUE(UINT32, UInt32)
403 COPY_VALUE(UINT64, UInt64) 380 COPY_VALUE(UINT64, UInt64)
404 COPY_VALUE(FLOAT, Float) 381 COPY_VALUE(FLOAT, Float)
405 COPY_VALUE(DOUBLE, Double) 382 COPY_VALUE(DOUBLE, Double)
406 COPY_VALUE(ENUM, Enum) 383 COPY_VALUE(ENUM, Enum)
407 COPY_VALUE(STRING, String) 384 COPY_VALUE(STRING, String)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 ->MergeFrom( 426 ->MergeFrom(
450 source_reflection->GetRepeatedMessage(source, field, i)); 427 source_reflection->GetRepeatedMessage(source, field, i));
451 } 428 }
452 break; 429 break;
453 } 430 }
454 } 431 }
455 } 432 }
456 } 433 }
457 } 434 }
458 435
459 void FieldMaskTree::TrimMessage(const Node* node, Message* message) {
460 GOOGLE_DCHECK(!node->children.empty());
461 const Reflection* reflection = message->GetReflection();
462 const Descriptor* descriptor = message->GetDescriptor();
463 const int32 field_count = descriptor->field_count();
464 for (int index = 0; index < field_count; ++index) {
465 const FieldDescriptor* field = descriptor->field(index);
466 map<string, Node*>::const_iterator it = node->children.find(field->name());
467 if (it == node->children.end()) {
468 reflection->ClearField(message, field);
469 } else {
470 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
471 Node* child = it->second;
472 if (!child->children.empty()) {
473 TrimMessage(child, reflection->MutableMessage(message, field));
474 }
475 }
476 }
477 }
478 }
479
480 } // namespace 436 } // namespace
481 437
482 void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) { 438 void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
483 FieldMaskTree tree; 439 FieldMaskTree tree;
484 tree.MergeFromFieldMask(mask); 440 tree.MergeFromFieldMask(mask);
485 out->Clear(); 441 out->Clear();
486 tree.MergeToFieldMask(out); 442 tree.MergeToFieldMask(out);
487 } 443 }
488 444
489 void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2, 445 void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 const MergeOptions& options, 482 const MergeOptions& options,
527 Message* destination) { 483 Message* destination) {
528 GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor()); 484 GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
529 // Build a FieldMaskTree and walk through the tree to merge all specified 485 // Build a FieldMaskTree and walk through the tree to merge all specified
530 // fields. 486 // fields.
531 FieldMaskTree tree; 487 FieldMaskTree tree;
532 tree.MergeFromFieldMask(mask); 488 tree.MergeFromFieldMask(mask);
533 tree.MergeMessage(source, options, destination); 489 tree.MergeMessage(source, options, destination);
534 } 490 }
535 491
536 void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) {
537 // Build a FieldMaskTree and walk through the tree to merge all specified
538 // fields.
539 FieldMaskTree tree;
540 tree.MergeFromFieldMask(mask);
541 tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
542 }
543
544 } // namespace util 492 } // namespace util
545 } // namespace protobuf 493 } // namespace protobuf
546 } // namespace google 494 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698