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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component 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 vector<string> paths = Split(str, ","); 48 std::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 vector<string> paths = Split(str, ","); 119 std::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::InternalIsValidPath(const Descriptor* descriptor, 131 bool FieldMaskUtil::GetFieldDescriptors(
132 StringPiece path) { 132 const Descriptor* descriptor, StringPiece path,
133 vector<string> parts = Split(path, "."); 133 std::vector<const FieldDescriptor*>* field_descriptors) {
134 if (field_descriptors != NULL) {
135 field_descriptors->clear();
136 }
137 std::vector<string> parts = Split(path, ".");
134 for (int i = 0; i < parts.size(); ++i) { 138 for (int i = 0; i < parts.size(); ++i) {
135 const string& field_name = parts[i]; 139 const string& field_name = parts[i];
136 if (descriptor == NULL) { 140 if (descriptor == NULL) {
137 return false; 141 return false;
138 } 142 }
139 const FieldDescriptor* field = descriptor->FindFieldByName(field_name); 143 const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
140 if (field == NULL) { 144 if (field == NULL) {
141 return false; 145 return false;
142 } 146 }
147 if (field_descriptors != NULL) {
148 field_descriptors->push_back(field);
149 }
143 if (!field->is_repeated() && 150 if (!field->is_repeated() &&
144 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 151 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
145 descriptor = field->message_type(); 152 descriptor = field->message_type();
146 } else { 153 } else {
147 descriptor = NULL; 154 descriptor = NULL;
148 } 155 }
149 } 156 }
150 return true; 157 return true;
151 } 158 }
152 159
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 void MergeMessage(const Message& source, 200 void MergeMessage(const Message& source,
194 const FieldMaskUtil::MergeOptions& options, 201 const FieldMaskUtil::MergeOptions& options,
195 Message* destination) { 202 Message* destination) {
196 // Do nothing if the tree is empty. 203 // Do nothing if the tree is empty.
197 if (root_.children.empty()) { 204 if (root_.children.empty()) {
198 return; 205 return;
199 } 206 }
200 MergeMessage(&root_, source, options, destination); 207 MergeMessage(&root_, source, options, destination);
201 } 208 }
202 209
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
203 private: 219 private:
204 struct Node { 220 struct Node {
205 Node() {} 221 Node() {}
206 222
207 ~Node() { ClearChildren(); } 223 ~Node() { ClearChildren(); }
208 224
209 void ClearChildren() { 225 void ClearChildren() {
210 for (map<string, Node*>::iterator it = children.begin(); 226 for (std::map<string, Node*>::iterator it = children.begin();
211 it != children.end(); ++it) { 227 it != children.end(); ++it) {
212 delete it->second; 228 delete it->second;
213 } 229 }
214 children.clear(); 230 children.clear();
215 } 231 }
216 232
217 map<string, Node*> children; 233 std::map<string, Node*> children;
218 234
219 private: 235 private:
220 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); 236 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
221 }; 237 };
222 238
223 // Merge a sub-tree to mask. This method adds the field paths represented 239 // Merge a sub-tree to mask. This method adds the field paths represented
224 // by all leaf nodes descended from "node" to mask. 240 // by all leaf nodes descended from "node" to mask.
225 void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out); 241 void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
226 242
227 // Merge all leaf nodes of a sub-tree to another tree. 243 // Merge all leaf nodes of a sub-tree to another tree.
228 void MergeLeafNodesToTree(const string& prefix, const Node* node, 244 void MergeLeafNodesToTree(const string& prefix, const Node* node,
229 FieldMaskTree* out); 245 FieldMaskTree* out);
230 246
231 // Merge all fields specified by a sub-tree from one message to another. 247 // Merge all fields specified by a sub-tree from one message to another.
232 void MergeMessage(const Node* node, const Message& source, 248 void MergeMessage(const Node* node, const Message& source,
233 const FieldMaskUtil::MergeOptions& options, 249 const FieldMaskUtil::MergeOptions& options,
234 Message* destination); 250 Message* destination);
235 251
252 // Trims all fields not specified by this sub-tree from the given message.
253 void TrimMessage(const Node* node, Message* message);
254
236 Node root_; 255 Node root_;
237 256
238 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree); 257 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
239 }; 258 };
240 259
241 FieldMaskTree::FieldMaskTree() {} 260 FieldMaskTree::FieldMaskTree() {}
242 261
243 FieldMaskTree::~FieldMaskTree() {} 262 FieldMaskTree::~FieldMaskTree() {}
244 263
245 void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) { 264 void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
246 for (int i = 0; i < mask.paths_size(); ++i) { 265 for (int i = 0; i < mask.paths_size(); ++i) {
247 AddPath(mask.paths(i)); 266 AddPath(mask.paths(i));
248 } 267 }
249 } 268 }
250 269
251 void FieldMaskTree::MergeToFieldMask(FieldMask* mask) { 270 void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
252 MergeToFieldMask("", &root_, mask); 271 MergeToFieldMask("", &root_, mask);
253 } 272 }
254 273
255 void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node, 274 void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
256 FieldMask* out) { 275 FieldMask* out) {
257 if (node->children.empty()) { 276 if (node->children.empty()) {
258 if (prefix.empty()) { 277 if (prefix.empty()) {
259 // This is the root node. 278 // This is the root node.
260 return; 279 return;
261 } 280 }
262 out->add_paths(prefix); 281 out->add_paths(prefix);
263 return; 282 return;
264 } 283 }
265 for (map<string, Node*>::const_iterator it = node->children.begin(); 284 for (std::map<string, Node*>::const_iterator it = node->children.begin();
266 it != node->children.end(); ++it) { 285 it != node->children.end(); ++it) {
267 string current_path = prefix.empty() ? it->first : prefix + "." + it->first; 286 string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
268 MergeToFieldMask(current_path, it->second, out); 287 MergeToFieldMask(current_path, it->second, out);
269 } 288 }
270 } 289 }
271 290
272 void FieldMaskTree::AddPath(const string& path) { 291 void FieldMaskTree::AddPath(const string& path) {
273 vector<string> parts = Split(path, "."); 292 std::vector<string> parts = Split(path, ".");
274 if (parts.empty()) { 293 if (parts.empty()) {
275 return; 294 return;
276 } 295 }
277 bool new_branch = false; 296 bool new_branch = false;
278 Node* node = &root_; 297 Node* node = &root_;
279 for (int i = 0; i < parts.size(); ++i) { 298 for (int i = 0; i < parts.size(); ++i) {
280 if (!new_branch && node != &root_ && node->children.empty()) { 299 if (!new_branch && node != &root_ && node->children.empty()) {
281 // Path matches an existing leaf node. This means the path is already 300 // Path matches an existing leaf node. This means the path is already
282 // coverred by this tree (for example, adding "foo.bar.baz" to a tree 301 // coverred by this tree (for example, adding "foo.bar.baz" to a tree
283 // which already contains "foo.bar"). 302 // which already contains "foo.bar").
284 return; 303 return;
285 } 304 }
286 const string& node_name = parts[i]; 305 const string& node_name = parts[i];
287 Node*& child = node->children[node_name]; 306 Node*& child = node->children[node_name];
288 if (child == NULL) { 307 if (child == NULL) {
289 new_branch = true; 308 new_branch = true;
290 child = new Node(); 309 child = new Node();
291 } 310 }
292 node = child; 311 node = child;
293 } 312 }
294 if (!node->children.empty()) { 313 if (!node->children.empty()) {
295 node->ClearChildren(); 314 node->ClearChildren();
296 } 315 }
297 } 316 }
298 317
299 void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) { 318 void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
300 vector<string> parts = Split(path, "."); 319 std::vector<string> parts = Split(path, ".");
301 if (parts.empty()) { 320 if (parts.empty()) {
302 return; 321 return;
303 } 322 }
304 const Node* node = &root_; 323 const Node* node = &root_;
305 for (int i = 0; i < parts.size(); ++i) { 324 for (int i = 0; i < parts.size(); ++i) {
306 if (node->children.empty()) { 325 if (node->children.empty()) {
307 if (node != &root_) { 326 if (node != &root_) {
308 out->AddPath(path); 327 out->AddPath(path);
309 } 328 }
310 return; 329 return;
311 } 330 }
312 const string& node_name = parts[i]; 331 const string& node_name = parts[i];
313 const Node* result = FindPtrOrNull(node->children, node_name); 332 const Node* result = FindPtrOrNull(node->children, node_name);
314 if (result == NULL) { 333 if (result == NULL) {
315 // No intersection found. 334 // No intersection found.
316 return; 335 return;
317 } 336 }
318 node = result; 337 node = result;
319 } 338 }
320 // Now we found a matching node with the given path. Add all leaf nodes 339 // Now we found a matching node with the given path. Add all leaf nodes
321 // to out. 340 // to out.
322 MergeLeafNodesToTree(path, node, out); 341 MergeLeafNodesToTree(path, node, out);
323 } 342 }
324 343
325 void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node, 344 void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
326 FieldMaskTree* out) { 345 FieldMaskTree* out) {
327 if (node->children.empty()) { 346 if (node->children.empty()) {
328 out->AddPath(prefix); 347 out->AddPath(prefix);
329 } 348 }
330 for (map<string, Node*>::const_iterator it = node->children.begin(); 349 for (std::map<string, Node*>::const_iterator it = node->children.begin();
331 it != node->children.end(); ++it) { 350 it != node->children.end(); ++it) {
332 string current_path = prefix.empty() ? it->first : prefix + "." + it->first; 351 string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
333 MergeLeafNodesToTree(current_path, it->second, out); 352 MergeLeafNodesToTree(current_path, it->second, out);
334 } 353 }
335 } 354 }
336 355
337 void FieldMaskTree::MergeMessage(const Node* node, const Message& source, 356 void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
338 const FieldMaskUtil::MergeOptions& options, 357 const FieldMaskUtil::MergeOptions& options,
339 Message* destination) { 358 Message* destination) {
340 GOOGLE_DCHECK(!node->children.empty()); 359 GOOGLE_DCHECK(!node->children.empty());
341 const Reflection* source_reflection = source.GetReflection(); 360 const Reflection* source_reflection = source.GetReflection();
342 const Reflection* destination_reflection = destination->GetReflection(); 361 const Reflection* destination_reflection = destination->GetReflection();
343 const Descriptor* descriptor = source.GetDescriptor(); 362 const Descriptor* descriptor = source.GetDescriptor();
344 for (map<string, Node*>::const_iterator it = node->children.begin(); 363 for (std::map<string, Node*>::const_iterator it = node->children.begin();
345 it != node->children.end(); ++it) { 364 it != node->children.end(); ++it) {
346 const string& field_name = it->first; 365 const string& field_name = it->first;
347 const Node* child = it->second; 366 const Node* child = it->second;
348 const FieldDescriptor* field = descriptor->FindFieldByName(field_name); 367 const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
349 if (field == NULL) { 368 if (field == NULL) {
350 GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in messag e " 369 GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in messag e "
351 << descriptor->full_name(); 370 << descriptor->full_name();
352 continue; 371 continue;
353 } 372 }
354 if (!child->children.empty()) { 373 if (!child->children.empty()) {
355 // Sub-paths are only allowed for singular message fields. 374 // Sub-paths are only allowed for singular message fields.
356 if (field->is_repeated() || 375 if (field->is_repeated() ||
357 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 376 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
358 GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message " 377 GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
359 << descriptor->full_name() 378 << descriptor->full_name()
360 << " is not a singular message field and cannot " 379 << " is not a singular message field and cannot "
361 << "have sub-fields."; 380 << "have sub-fields.";
362 continue; 381 continue;
363 } 382 }
364 MergeMessage(child, source_reflection->GetMessage(source, field), options, 383 MergeMessage(child, source_reflection->GetMessage(source, field), options,
365 destination_reflection->MutableMessage(destination, field)); 384 destination_reflection->MutableMessage(destination, field));
366 continue; 385 continue;
367 } 386 }
368 if (!field->is_repeated()) { 387 if (!field->is_repeated()) {
369 switch (field->cpp_type()) { 388 switch (field->cpp_type()) {
370 #define COPY_VALUE(TYPE, Name) \ 389 #define COPY_VALUE(TYPE, Name) \
371 case FieldDescriptor::CPPTYPE_##TYPE: { \ 390 case FieldDescriptor::CPPTYPE_##TYPE: { \
372 destination_reflection->Set##Name( \ 391 if (source_reflection->HasField(source, field)) { \
373 destination, field, source_reflection->Get##Name(source, field)); \ 392 destination_reflection->Set##Name( \
374 break; \ 393 destination, field, source_reflection->Get##Name(source, field)); \
394 } else { \
395 destination_reflection->ClearField(destination, field); \
396 } \
397 break; \
375 } 398 }
376 COPY_VALUE(BOOL, Bool) 399 COPY_VALUE(BOOL, Bool)
377 COPY_VALUE(INT32, Int32) 400 COPY_VALUE(INT32, Int32)
378 COPY_VALUE(INT64, Int64) 401 COPY_VALUE(INT64, Int64)
379 COPY_VALUE(UINT32, UInt32) 402 COPY_VALUE(UINT32, UInt32)
380 COPY_VALUE(UINT64, UInt64) 403 COPY_VALUE(UINT64, UInt64)
381 COPY_VALUE(FLOAT, Float) 404 COPY_VALUE(FLOAT, Float)
382 COPY_VALUE(DOUBLE, Double) 405 COPY_VALUE(DOUBLE, Double)
383 COPY_VALUE(ENUM, Enum) 406 COPY_VALUE(ENUM, Enum)
384 COPY_VALUE(STRING, String) 407 COPY_VALUE(STRING, String)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 ->MergeFrom( 449 ->MergeFrom(
427 source_reflection->GetRepeatedMessage(source, field, i)); 450 source_reflection->GetRepeatedMessage(source, field, i));
428 } 451 }
429 break; 452 break;
430 } 453 }
431 } 454 }
432 } 455 }
433 } 456 }
434 } 457 }
435 458
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
436 } // namespace 480 } // namespace
437 481
438 void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) { 482 void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
439 FieldMaskTree tree; 483 FieldMaskTree tree;
440 tree.MergeFromFieldMask(mask); 484 tree.MergeFromFieldMask(mask);
441 out->Clear(); 485 out->Clear();
442 tree.MergeToFieldMask(out); 486 tree.MergeToFieldMask(out);
443 } 487 }
444 488
445 void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2, 489 void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 const MergeOptions& options, 526 const MergeOptions& options,
483 Message* destination) { 527 Message* destination) {
484 GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor()); 528 GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
485 // Build a FieldMaskTree and walk through the tree to merge all specified 529 // Build a FieldMaskTree and walk through the tree to merge all specified
486 // fields. 530 // fields.
487 FieldMaskTree tree; 531 FieldMaskTree tree;
488 tree.MergeFromFieldMask(mask); 532 tree.MergeFromFieldMask(mask);
489 tree.MergeMessage(source, options, destination); 533 tree.MergeMessage(source, options, destination);
490 } 534 }
491 535
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
492 } // namespace util 544 } // namespace util
493 } // namespace protobuf 545 } // namespace protobuf
494 } // namespace google 546 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698