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

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/internal/proto_writer.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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 using util::StatusOr; 57 using util::StatusOr;
58 58
59 59
60 ProtoWriter::ProtoWriter(TypeResolver* type_resolver, 60 ProtoWriter::ProtoWriter(TypeResolver* type_resolver,
61 const google::protobuf::Type& type, 61 const google::protobuf::Type& type,
62 strings::ByteSink* output, ErrorListener* listener) 62 strings::ByteSink* output, ErrorListener* listener)
63 : master_type_(type), 63 : master_type_(type),
64 typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), 64 typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
65 own_typeinfo_(true), 65 own_typeinfo_(true),
66 done_(false), 66 done_(false),
67 ignore_unknown_fields_(false),
68 use_lower_camel_for_enums_(false),
67 element_(NULL), 69 element_(NULL),
68 size_insert_(), 70 size_insert_(),
69 output_(output), 71 output_(output),
70 buffer_(), 72 buffer_(),
71 adapter_(&buffer_), 73 adapter_(&buffer_),
72 stream_(new CodedOutputStream(&adapter_)), 74 stream_(new CodedOutputStream(&adapter_)),
73 listener_(listener), 75 listener_(listener),
74 invalid_depth_(0), 76 invalid_depth_(0),
75 tracker_(new ObjectLocationTracker()) {} 77 tracker_(new ObjectLocationTracker()) {}
76 78
77 ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, 79 ProtoWriter::ProtoWriter(const TypeInfo* typeinfo,
78 const google::protobuf::Type& type, 80 const google::protobuf::Type& type,
79 strings::ByteSink* output, ErrorListener* listener) 81 strings::ByteSink* output, ErrorListener* listener)
80 : master_type_(type), 82 : master_type_(type),
81 typeinfo_(typeinfo), 83 typeinfo_(typeinfo),
82 own_typeinfo_(false), 84 own_typeinfo_(false),
83 done_(false), 85 done_(false),
86 ignore_unknown_fields_(false),
87 use_lower_camel_for_enums_(false),
84 element_(NULL), 88 element_(NULL),
85 size_insert_(), 89 size_insert_(),
86 output_(output), 90 output_(output),
87 buffer_(), 91 buffer_(),
88 adapter_(&buffer_), 92 adapter_(&buffer_),
89 stream_(new CodedOutputStream(&adapter_)), 93 stream_(new CodedOutputStream(&adapter_)),
90 listener_(listener), 94 listener_(listener),
91 invalid_depth_(0), 95 invalid_depth_(0),
92 tracker_(new ObjectLocationTracker()) {} 96 tracker_(new ObjectLocationTracker()) {}
93 97
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 StatusOr<string> s = data.ToString(); 259 StatusOr<string> s = data.ToString();
256 if (s.ok()) { 260 if (s.ok()) {
257 WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream); 261 WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream);
258 } 262 }
259 return s.status(); 263 return s.status();
260 } 264 }
261 265
262 // Writes an ENUM field, including tag, to the stream. 266 // Writes an ENUM field, including tag, to the stream.
263 inline Status WriteEnum(int field_number, const DataPiece& data, 267 inline Status WriteEnum(int field_number, const DataPiece& data,
264 const google::protobuf::Enum* enum_type, 268 const google::protobuf::Enum* enum_type,
265 CodedOutputStream* stream) { 269 CodedOutputStream* stream,
266 StatusOr<int> e = data.ToEnum(enum_type); 270 bool use_lower_camel_for_enums) {
271 StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums);
267 if (e.ok()) { 272 if (e.ok()) {
268 WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream); 273 WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
269 } 274 }
270 return e.status(); 275 return e.status();
271 } 276 }
272 277
273 // Given a google::protobuf::Type, returns the set of all required fields. 278 // Given a google::protobuf::Type, returns the set of all required fields.
274 std::set<const google::protobuf::Field*> GetRequiredFields( 279 std::set<const google::protobuf::Field*> GetRequiredFields(
275 const google::protobuf::Type& type) { 280 const google::protobuf::Type& type) {
276 std::set<const google::protobuf::Field*> required; 281 std::set<const google::protobuf::Field*> required;
277 for (int i = 0; i < type.fields_size(); i++) { 282 for (int i = 0; i < type.fields_size(); i++) {
278 const google::protobuf::Field& field = type.fields(i); 283 const google::protobuf::Field& field = type.fields(i);
279 if (field.cardinality() == 284 if (field.cardinality() ==
280 google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) { 285 google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) {
281 required.insert(&field); 286 required.insert(&field);
282 } 287 }
283 } 288 }
284 return required; 289 return required;
285 } 290 }
286 291
287 } // namespace 292 } // namespace
288 293
289 ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo, 294 ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo,
290 const google::protobuf::Type& type, 295 const google::protobuf::Type& type,
291 ProtoWriter* enclosing) 296 ProtoWriter* enclosing)
292 : BaseElement(NULL), 297 : BaseElement(NULL),
293 ow_(enclosing), 298 ow_(enclosing),
294 parent_field_(NULL), 299 parent_field_(NULL),
295 typeinfo_(typeinfo), 300 typeinfo_(typeinfo),
301 proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
296 type_(type), 302 type_(type),
297 required_fields_(GetRequiredFields(type)),
298 size_index_(-1), 303 size_index_(-1),
299 array_index_(-1) {} 304 array_index_(-1),
305 // oneof_indices_ values are 1-indexed (0 means not present).
306 oneof_indices_(type.oneofs_size() + 1) {
307 if (!proto3_) {
308 required_fields_ = GetRequiredFields(type_);
309 }
310 }
300 311
301 ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, 312 ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent,
302 const google::protobuf::Field* field, 313 const google::protobuf::Field* field,
303 const google::protobuf::Type& type, 314 const google::protobuf::Type& type,
304 bool is_list) 315 bool is_list)
305 : BaseElement(parent), 316 : BaseElement(parent),
306 ow_(this->parent()->ow_), 317 ow_(this->parent()->ow_),
307 parent_field_(field), 318 parent_field_(field),
308 typeinfo_(this->parent()->typeinfo_), 319 typeinfo_(this->parent()->typeinfo_),
320 proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
309 type_(type), 321 type_(type),
310 size_index_( 322 size_index_(
311 !is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE 323 !is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
312 ? ow_->size_insert_.size() 324 ? ow_->size_insert_.size()
313 : -1), 325 : -1),
314 array_index_(is_list ? 0 : -1) { 326 array_index_(is_list ? 0 : -1),
327 // oneof_indices_ values are 1-indexed (0 means not present).
328 oneof_indices_(type_.oneofs_size() + 1) {
315 if (!is_list) { 329 if (!is_list) {
316 if (ow_->IsRepeated(*field)) { 330 if (ow_->IsRepeated(*field)) {
317 // Update array_index_ if it is an explicit list. 331 // Update array_index_ if it is an explicit list.
318 if (this->parent()->array_index_ >= 0) this->parent()->array_index_++; 332 if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
319 } else { 333 } else if (!proto3_) {
334 // For required fields tracking.
320 this->parent()->RegisterField(field); 335 this->parent()->RegisterField(field);
321 } 336 }
322 337
323 if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) { 338 if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
324 required_fields_ = GetRequiredFields(type_); 339 if (!proto3_) {
340 required_fields_ = GetRequiredFields(type_);
341 }
325 int start_pos = ow_->stream_->ByteCount(); 342 int start_pos = ow_->stream_->ByteCount();
326 // length of serialized message is the final buffer position minus 343 // length of serialized message is the final buffer position minus
327 // starting buffer position, plus length adjustments for size fields 344 // starting buffer position, plus length adjustments for size fields
328 // of any nested messages. We start with -start_pos here, so we only 345 // of any nested messages. We start with -start_pos here, so we only
329 // need to add the final buffer position to it at the end. 346 // need to add the final buffer position to it at the end.
330 SizeInfo info = {start_pos, -start_pos}; 347 SizeInfo info = {start_pos, -start_pos};
331 ow_->size_insert_.push_back(info); 348 ow_->size_insert_.push_back(info);
332 } 349 }
333 } 350 }
334 } 351 }
335 352
336 ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { 353 ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() {
337 // Calls the registered error listener for any required field(s) not yet 354 if (!proto3_) {
338 // seen. 355 // Calls the registered error listener for any required field(s) not yet
339 for (set<const google::protobuf::Field*>::iterator it = 356 // seen.
340 required_fields_.begin(); 357 for (std::set<const google::protobuf::Field*>::iterator it =
341 it != required_fields_.end(); ++it) { 358 required_fields_.begin();
342 ow_->MissingField((*it)->name()); 359 it != required_fields_.end(); ++it) {
360 ow_->MissingField((*it)->name());
361 }
343 } 362 }
344 // Computes the total number of proto bytes used by a message, also adjusts 363 // Computes the total number of proto bytes used by a message, also adjusts
345 // the size of all parent messages by the length of this size field. 364 // the size of all parent messages by the length of this size field.
346 // If size_index_ < 0, this is not a message, so no size field is added. 365 // If size_index_ < 0, this is not a message, so no size field is added.
347 if (size_index_ >= 0) { 366 if (size_index_ >= 0) {
348 // Add the final buffer position to compute the total length of this 367 // Add the final buffer position to compute the total length of this
349 // serialized message. The stored value (before this addition) already 368 // serialized message. The stored value (before this addition) already
350 // contains the total length of the size fields of all nested messages 369 // contains the total length of the size fields of all nested messages
351 // minus the initial buffer position. 370 // minus the initial buffer position.
352 ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount(); 371 ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 StrAppend(&loc, "[\"", CEscape(name), "\"]"); 411 StrAppend(&loc, "[\"", CEscape(name), "\"]");
393 } 412 }
394 } 413 }
395 if (ow_->IsRepeated(*parent_field_) && array_index_ > 0) { 414 if (ow_->IsRepeated(*parent_field_) && array_index_ > 0) {
396 StrAppend(&loc, "[", array_index_ - 1, "]"); 415 StrAppend(&loc, "[", array_index_ - 1, "]");
397 } 416 }
398 return loc.empty() ? "." : loc; 417 return loc.empty() ? "." : loc;
399 } 418 }
400 419
401 bool ProtoWriter::ProtoElement::IsOneofIndexTaken(int32 index) { 420 bool ProtoWriter::ProtoElement::IsOneofIndexTaken(int32 index) {
402 return ContainsKey(oneof_indices_, index); 421 return oneof_indices_[index];
403 } 422 }
404 423
405 void ProtoWriter::ProtoElement::TakeOneofIndex(int32 index) { 424 void ProtoWriter::ProtoElement::TakeOneofIndex(int32 index) {
406 InsertIfNotPresent(&oneof_indices_, index); 425 oneof_indices_[index] = true;
407 } 426 }
408 427
409 void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) { 428 void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) {
410 listener_->InvalidName(location(), ToSnakeCase(unknown_name), message); 429 listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
411 } 430 }
412 431
413 void ProtoWriter::InvalidValue(StringPiece type_name, StringPiece value) { 432 void ProtoWriter::InvalidValue(StringPiece type_name, StringPiece value) {
414 listener_->InvalidValue(location(), type_name, value); 433 listener_->InvalidValue(location(), type_name, value);
415 } 434 }
416 435
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 return this; 573 return this;
555 } 574 }
556 575
557 ProtoWriter* ProtoWriter::RenderPrimitiveField( 576 ProtoWriter* ProtoWriter::RenderPrimitiveField(
558 const google::protobuf::Field& field, const google::protobuf::Type& type, 577 const google::protobuf::Field& field, const google::protobuf::Type& type,
559 const DataPiece& data) { 578 const DataPiece& data) {
560 Status status; 579 Status status;
561 580
562 // Pushing a ProtoElement and then pop it off at the end for 2 purposes: 581 // Pushing a ProtoElement and then pop it off at the end for 2 purposes:
563 // error location reporting and required field accounting. 582 // error location reporting and required field accounting.
564 element_.reset(new ProtoElement(element_.release(), &field, type, false)); 583 //
584 // For proto3, since there is no required field tracking, we only need to push
585 // ProtoElement for error cases.
586 if (!element_->proto3()) {
587 element_.reset(new ProtoElement(element_.release(), &field, type, false));
588 }
565 589
566 if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN || 590 if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN ||
567 field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) { 591 field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
592 // Push a ProtoElement for location reporting purposes.
593 if (element_->proto3()) {
594 element_.reset(new ProtoElement(element_.release(), &field, type, false));
595 }
568 InvalidValue(field.type_url().empty() 596 InvalidValue(field.type_url().empty()
569 ? google::protobuf::Field_Kind_Name(field.kind()) 597 ? google::protobuf::Field_Kind_Name(field.kind())
570 : field.type_url(), 598 : field.type_url(),
571 data.ValueAsStringOrDefault("")); 599 data.ValueAsStringOrDefault(""));
572 element_.reset(element()->pop()); 600 element_.reset(element()->pop());
573 return this; 601 return this;
574 } 602 }
575 603
576 switch (field.kind()) { 604 switch (field.kind()) {
577 case google::protobuf::Field_Kind_TYPE_INT32: { 605 case google::protobuf::Field_Kind_TYPE_INT32: {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 status = WriteBytes(field.number(), data, stream_.get()); 658 status = WriteBytes(field.number(), data, stream_.get());
631 break; 659 break;
632 } 660 }
633 case google::protobuf::Field_Kind_TYPE_STRING: { 661 case google::protobuf::Field_Kind_TYPE_STRING: {
634 status = WriteString(field.number(), data, stream_.get()); 662 status = WriteString(field.number(), data, stream_.get());
635 break; 663 break;
636 } 664 }
637 case google::protobuf::Field_Kind_TYPE_ENUM: { 665 case google::protobuf::Field_Kind_TYPE_ENUM: {
638 status = WriteEnum(field.number(), data, 666 status = WriteEnum(field.number(), data,
639 typeinfo_->GetEnumByTypeUrl(field.type_url()), 667 typeinfo_->GetEnumByTypeUrl(field.type_url()),
640 stream_.get()); 668 stream_.get(), use_lower_camel_for_enums_);
641 break; 669 break;
642 } 670 }
643 default: // TYPE_GROUP or TYPE_MESSAGE 671 default: // TYPE_GROUP or TYPE_MESSAGE
644 status = Status(INVALID_ARGUMENT, data.ToString().ValueOrDie()); 672 status = Status(INVALID_ARGUMENT, data.ToString().ValueOrDie());
645 } 673 }
646 674
647 if (!status.ok()) { 675 if (!status.ok()) {
676 // Push a ProtoElement for location reporting purposes.
677 if (element_->proto3()) {
678 element_.reset(new ProtoElement(element_.release(), &field, type, false));
679 }
648 InvalidValue(google::protobuf::Field_Kind_Name(field.kind()), 680 InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
649 status.error_message()); 681 status.error_message());
682 element_.reset(element()->pop());
683 return this;
650 } 684 }
651 685
652 element_.reset(element()->pop()); 686 if (!element_->proto3()) element_.reset(element()->pop());
687
653 return this; 688 return this;
654 } 689 }
655 690
656 const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name, 691 const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name,
657 bool is_list) { 692 bool is_list) {
658 if (invalid_depth_ > 0) { 693 if (invalid_depth_ > 0) {
659 ++invalid_depth_; 694 ++invalid_depth_;
660 return NULL; 695 return NULL;
661 } 696 }
662 const google::protobuf::Field* field = Lookup(name); 697 const google::protobuf::Field* field = Lookup(name);
(...skipping 22 matching lines...) Expand all
685 if (e->parent_field() == NULL) { 720 if (e->parent_field() == NULL) {
686 InvalidName(unnormalized_name, "Proto fields must have a name."); 721 InvalidName(unnormalized_name, "Proto fields must have a name.");
687 } else if (!IsRepeated(*e->parent_field())) { 722 } else if (!IsRepeated(*e->parent_field())) {
688 InvalidName(unnormalized_name, "Proto fields must have a name."); 723 InvalidName(unnormalized_name, "Proto fields must have a name.");
689 return NULL; 724 return NULL;
690 } 725 }
691 return e->parent_field(); 726 return e->parent_field();
692 } 727 }
693 const google::protobuf::Field* field = 728 const google::protobuf::Field* field =
694 typeinfo_->FindField(&e->type(), unnormalized_name); 729 typeinfo_->FindField(&e->type(), unnormalized_name);
695 if (field == NULL) InvalidName(unnormalized_name, "Cannot find field."); 730 if (field == NULL && !ignore_unknown_fields_) {
731 InvalidName(unnormalized_name, "Cannot find field.");
732 }
696 return field; 733 return field;
697 } 734 }
698 735
699 const google::protobuf::Type* ProtoWriter::LookupType( 736 const google::protobuf::Type* ProtoWriter::LookupType(
700 const google::protobuf::Field* field) { 737 const google::protobuf::Field* field) {
701 return ((field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE || 738 return ((field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE ||
702 field->kind() == google::protobuf::Field_Kind_TYPE_GROUP) 739 field->kind() == google::protobuf::Field_Kind_TYPE_GROUP)
703 ? typeinfo_->GetTypeByTypeUrl(field->type_url()) 740 ? typeinfo_->GetTypeByTypeUrl(field->type_url())
704 : &element_->type()); 741 : &element_->type());
705 } 742 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( 790 WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
754 static_cast<WireFormatLite::FieldType>(field.kind())); 791 static_cast<WireFormatLite::FieldType>(field.kind()));
755 stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type)); 792 stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type));
756 } 793 }
757 794
758 795
759 } // namespace converter 796 } // namespace converter
760 } // namespace util 797 } // namespace util
761 } // namespace protobuf 798 } // namespace protobuf
762 } // namespace google 799 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698