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

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 using util::StatusOr; 56 using util::StatusOr;
57 57
58 58
59 ProtoStreamObjectWriter::ProtoStreamObjectWriter( 59 ProtoStreamObjectWriter::ProtoStreamObjectWriter(
60 TypeResolver* type_resolver, const google::protobuf::Type& type, 60 TypeResolver* type_resolver, const google::protobuf::Type& type,
61 strings::ByteSink* output, ErrorListener* listener, 61 strings::ByteSink* output, ErrorListener* listener,
62 const ProtoStreamObjectWriter::Options& options) 62 const ProtoStreamObjectWriter::Options& options)
63 : ProtoWriter(type_resolver, type, output, listener), 63 : ProtoWriter(type_resolver, type, output, listener),
64 master_type_(type), 64 master_type_(type),
65 current_(NULL), 65 current_(NULL),
66 options_(options) { 66 options_(options) {}
67 set_ignore_unknown_fields(options_.ignore_unknown_fields);
68 set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums);
69 }
70 67
71 ProtoStreamObjectWriter::ProtoStreamObjectWriter( 68 ProtoStreamObjectWriter::ProtoStreamObjectWriter(
72 const TypeInfo* typeinfo, const google::protobuf::Type& type, 69 const TypeInfo* typeinfo, const google::protobuf::Type& type,
73 strings::ByteSink* output, ErrorListener* listener) 70 strings::ByteSink* output, ErrorListener* listener)
74 : ProtoWriter(typeinfo, type, output, listener), 71 : ProtoWriter(typeinfo, type, output, listener),
75 master_type_(type), 72 master_type_(type),
76 current_(NULL), 73 current_(NULL),
77 options_(ProtoStreamObjectWriter::Options::Defaults()) {} 74 options_(ProtoStreamObjectWriter::Options::Defaults()) {}
78 75
79 ProtoStreamObjectWriter::~ProtoStreamObjectWriter() { 76 ProtoStreamObjectWriter::~ProtoStreamObjectWriter() {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 output_(&data_), 183 output_(&data_),
187 depth_(0), 184 depth_(0),
188 is_well_known_type_(false), 185 is_well_known_type_(false),
189 well_known_type_render_(NULL) {} 186 well_known_type_render_(NULL) {}
190 187
191 ProtoStreamObjectWriter::AnyWriter::~AnyWriter() {} 188 ProtoStreamObjectWriter::AnyWriter::~AnyWriter() {}
192 189
193 void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) { 190 void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) {
194 ++depth_; 191 ++depth_;
195 // If an object writer is absent, that means we have not called StartAny() 192 // If an object writer is absent, that means we have not called StartAny()
196 // before reaching here, which happens when we have data before the "@type" 193 // before reaching here. This is an invalid state. StartAny() gets called
197 // field. 194 // whenever we see an "@type" being rendered (see AnyWriter::RenderDataPiece).
198 if (ow_ == NULL) { 195 if (ow_ == NULL) {
199 // Save data before the "@type" field for later replay. 196 // Make sure we are not already in an invalid state. This avoids making
200 uninterpreted_events_.push_back(Event(Event::START_OBJECT, name)); 197 // multiple unnecessary InvalidValue calls.
198 if (!invalid_) {
199 parent_->InvalidValue("Any",
200 StrCat("Missing or invalid @type for any field in ",
201 parent_->master_type_.name()));
202 invalid_ = true;
203 }
201 } else if (is_well_known_type_ && depth_ == 1) { 204 } else if (is_well_known_type_ && depth_ == 1) {
202 // For well-known types, the only other field besides "@type" should be a 205 // For well-known types, the only other field besides "@type" should be a
203 // "value" field. 206 // "value" field.
204 if (name != "value" && !invalid_) { 207 if (name != "value" && !invalid_) {
205 parent_->InvalidValue("Any", 208 parent_->InvalidValue("Any",
206 "Expect a \"value\" field for well-known types."); 209 "Expect a \"value\" field for well-known types.");
207 invalid_ = true; 210 invalid_ = true;
208 } 211 }
209 ow_->StartObject(""); 212 ow_->StartObject("");
210 } else { 213 } else {
211 // Forward the call to the child writer if: 214 // Forward the call to the child writer if:
212 // 1. the type is not a well-known type. 215 // 1. the type is not a well-known type.
213 // 2. or, we are in a nested Any, Struct, or Value object. 216 // 2. or, we are in a nested Any, Struct, or Value object.
214 ow_->StartObject(name); 217 ow_->StartObject(name);
215 } 218 }
216 } 219 }
217 220
218 bool ProtoStreamObjectWriter::AnyWriter::EndObject() { 221 bool ProtoStreamObjectWriter::AnyWriter::EndObject() {
219 --depth_; 222 --depth_;
220 if (ow_ == NULL) { 223 // As long as depth_ >= 0, we know we haven't reached the end of Any.
221 if (depth_ >= 0) { 224 // Propagate these EndObject() calls to the contained ow_. For regular
222 // Save data before the "@type" field for later replay. 225 // message types, we propagate the end of Any as well.
223 uninterpreted_events_.push_back(Event(Event::END_OBJECT)); 226 if (ow_ != NULL && (depth_ >= 0 || !is_well_known_type_)) {
224 }
225 } else if (depth_ >= 0 || !is_well_known_type_) {
226 // As long as depth_ >= 0, we know we haven't reached the end of Any.
227 // Propagate these EndObject() calls to the contained ow_. For regular
228 // message types, we propagate the end of Any as well.
229 ow_->EndObject(); 227 ow_->EndObject();
230 } 228 }
231 // A negative depth_ implies that we have reached the end of Any 229 // A negative depth_ implies that we have reached the end of Any
232 // object. Now we write out its contents. 230 // object. Now we write out its contents.
233 if (depth_ < 0) { 231 if (depth_ < 0) {
234 WriteAny(); 232 WriteAny();
235 return false; 233 return false;
236 } 234 }
237 return true; 235 return true;
238 } 236 }
239 237
240 void ProtoStreamObjectWriter::AnyWriter::StartList(StringPiece name) { 238 void ProtoStreamObjectWriter::AnyWriter::StartList(StringPiece name) {
241 ++depth_; 239 ++depth_;
240 // We expect ow_ to be present as this call only makes sense inside an Any.
242 if (ow_ == NULL) { 241 if (ow_ == NULL) {
243 // Save data before the "@type" field for later replay. 242 if (!invalid_) {
244 uninterpreted_events_.push_back(Event(Event::START_LIST, name)); 243 parent_->InvalidValue("Any",
244 StrCat("Missing or invalid @type for any field in ",
245 parent_->master_type_.name()));
246 invalid_ = true;
247 }
245 } else if (is_well_known_type_ && depth_ == 1) { 248 } else if (is_well_known_type_ && depth_ == 1) {
246 if (name != "value" && !invalid_) { 249 if (name != "value" && !invalid_) {
247 parent_->InvalidValue("Any", 250 parent_->InvalidValue("Any",
248 "Expect a \"value\" field for well-known types."); 251 "Expect a \"value\" field for well-known types.");
249 invalid_ = true; 252 invalid_ = true;
250 } 253 }
251 ow_->StartList(""); 254 ow_->StartList("");
252 } else { 255 } else {
253 ow_->StartList(name); 256 ow_->StartList(name);
254 } 257 }
255 } 258 }
256 259
257 void ProtoStreamObjectWriter::AnyWriter::EndList() { 260 void ProtoStreamObjectWriter::AnyWriter::EndList() {
258 --depth_; 261 --depth_;
259 if (depth_ < 0) { 262 if (depth_ < 0) {
260 GOOGLE_LOG(DFATAL) << "Mismatched EndList found, should not be possible"; 263 GOOGLE_LOG(DFATAL) << "Mismatched EndList found, should not be possible";
261 depth_ = 0; 264 depth_ = 0;
262 } 265 }
263 if (ow_ == NULL) { 266 // We don't write an error on the close, only on the open
264 // Save data before the "@type" field for later replay. 267 if (ow_ != NULL) {
265 uninterpreted_events_.push_back(Event(Event::END_LIST));
266 } else {
267 ow_->EndList(); 268 ow_->EndList();
268 } 269 }
269 } 270 }
270 271
271 void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece( 272 void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece(
272 StringPiece name, const DataPiece& value) { 273 StringPiece name, const DataPiece& value) {
273 // Start an Any only at depth_ 0. Other RenderDataPiece calls with "@type" 274 // Start an Any only at depth_ 0. Other RenderDataPiece calls with "@type"
274 // should go to the contained ow_ as they indicate nested Anys. 275 // should go to the contained ow_ as they indicate nested Anys.
275 if (depth_ == 0 && ow_ == NULL && name == "@type") { 276 if (depth_ == 0 && ow_ == NULL && name == "@type") {
276 StartAny(value); 277 StartAny(value);
277 } else if (ow_ == NULL) { 278 } else if (ow_ == NULL) {
278 // Save data before the "@type" field. 279 if (!invalid_) {
279 uninterpreted_events_.push_back(Event(name, value)); 280 parent_->InvalidValue("Any",
281 StrCat("Missing or invalid @type for any field in ",
282 parent_->master_type_.name()));
283 invalid_ = true;
284 }
280 } else if (depth_ == 0 && is_well_known_type_) { 285 } else if (depth_ == 0 && is_well_known_type_) {
281 if (name != "value" && !invalid_) { 286 if (name != "value" && !invalid_) {
282 parent_->InvalidValue("Any", 287 parent_->InvalidValue("Any",
283 "Expect a \"value\" field for well-known types."); 288 "Expect a \"value\" field for well-known types.");
284 invalid_ = true; 289 invalid_ = true;
285 } 290 }
286 if (well_known_type_render_ == NULL) { 291 if (well_known_type_render_ == NULL) {
287 // Only Any and Struct don't have a special type render but both of 292 // Only Any and Struct don't have a special type render but both of
288 // them expect a JSON object (i.e., a StartObject() call). 293 // them expect a JSON object (i.e., a StartObject() call).
289 if (value.type() != DataPiece::TYPE_NULL && !invalid_) { 294 if (!invalid_) {
290 parent_->InvalidValue("Any", "Expect a JSON object."); 295 parent_->InvalidValue("Any", "Expect a JSON object.");
291 invalid_ = true; 296 invalid_ = true;
292 } 297 }
293 } else { 298 } else {
294 ow_->ProtoWriter::StartObject(""); 299 ow_->ProtoWriter::StartObject("");
295 Status status = (*well_known_type_render_)(ow_.get(), value); 300 Status status = (*well_known_type_render_)(ow_.get(), value);
296 if (!status.ok()) ow_->InvalidValue("Any", status.error_message()); 301 if (!status.ok()) ow_->InvalidValue("Any", status.error_message());
297 ow_->ProtoWriter::EndObject(); 302 ow_->ProtoWriter::EndObject();
298 } 303 }
299 } else { 304 } else {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 // example: 349 // example:
345 // { 350 // {
346 // "@type": "type.googleapis.com/google.protobuf.Value", 351 // "@type": "type.googleapis.com/google.protobuf.Value",
347 // "value": [1, 2, 3], 352 // "value": [1, 2, 3],
348 // } 353 // }
349 // With the above JSON representation, we will only call StartList() on the 354 // With the above JSON representation, we will only call StartList() on the
350 // contained ow_. 355 // contained ow_.
351 if (!is_well_known_type_) { 356 if (!is_well_known_type_) {
352 ow_->StartObject(""); 357 ow_->StartObject("");
353 } 358 }
354
355 // Now we know the proto type and can interpret all data fields we gathered
356 // before the "@type" field.
357 for (int i = 0; i < uninterpreted_events_.size(); ++i) {
358 uninterpreted_events_[i].Replay(this);
359 }
360 } 359 }
361 360
362 void ProtoStreamObjectWriter::AnyWriter::WriteAny() { 361 void ProtoStreamObjectWriter::AnyWriter::WriteAny() {
363 if (ow_ == NULL) { 362 if (ow_ == NULL) {
364 if (uninterpreted_events_.empty()) { 363 // If we had no object writer, we never got any content, so just return
365 // We never got any content, so just return immediately, which is 364 // immediately, which is equivalent to writing an empty Any.
366 // equivalent to writing an empty Any. 365 return;
367 return;
368 } else {
369 // There are uninterpreted data, but we never got a "@type" field.
370 if (!invalid_) {
371 parent_->InvalidValue("Any", StrCat("Missing @type for any field in ",
372 parent_->master_type_.name()));
373 invalid_ = true;
374 }
375 return;
376 }
377 } 366 }
378 // Render the type_url and value fields directly to the stream. 367 // Render the type_url and value fields directly to the stream.
379 // type_url has tag 1 and value has tag 2. 368 // type_url has tag 1 and value has tag 2.
380 WireFormatLite::WriteString(1, type_url_, parent_->stream()); 369 WireFormatLite::WriteString(1, type_url_, parent_->stream());
381 if (!data_.empty()) { 370 if (!data_.empty()) {
382 WireFormatLite::WriteBytes(2, data_, parent_->stream()); 371 WireFormatLite::WriteBytes(2, data_, parent_->stream());
383 } 372 }
384 } 373 }
385 374
386 void ProtoStreamObjectWriter::AnyWriter::Event::Replay(
387 AnyWriter* writer) const {
388 switch (type_) {
389 case START_OBJECT:
390 writer->StartObject(name_);
391 break;
392 case END_OBJECT:
393 writer->EndObject();
394 break;
395 case START_LIST:
396 writer->StartList(name_);
397 break;
398 case END_LIST:
399 writer->EndList();
400 break;
401 case RENDER_DATA_PIECE:
402 writer->RenderDataPiece(name_, value_);
403 break;
404 }
405 }
406
407 void ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy() {
408 // DataPiece only contains a string reference. To make sure the referenced
409 // string value stays valid, we make a copy of the string value and update
410 // DataPiece to reference our own copy.
411 if (value_.type() == DataPiece::TYPE_STRING) {
412 value_.str().AppendToString(&value_storage_);
413 value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding());
414 } else if (value_.type() == DataPiece::TYPE_BYTES) {
415 value_storage_ = value_.ToBytes().ValueOrDie();
416 value_ =
417 DataPiece(value_storage_, true, value_.use_strict_base64_decoding());
418 }
419 }
420
421 ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing, 375 ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing,
422 ItemType item_type, bool is_placeholder, 376 ItemType item_type, bool is_placeholder,
423 bool is_list) 377 bool is_list)
424 : BaseElement(NULL), 378 : BaseElement(NULL),
425 ow_(enclosing), 379 ow_(enclosing),
426 any_(), 380 any_(),
427 item_type_(item_type), 381 item_type_(item_type),
428 is_placeholder_(is_placeholder), 382 is_placeholder_(is_placeholder),
429 is_list_(is_list) { 383 is_list_(is_list) {
430 if (item_type_ == ANY) { 384 if (item_type_ == ANY) {
431 any_.reset(new AnyWriter(ow_)); 385 any_.reset(new AnyWriter(ow_));
432 } 386 }
433 if (item_type == MAP) {
434 map_keys_.reset(new hash_set<string>);
435 }
436 } 387 }
437 388
438 ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent, 389 ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent,
439 ItemType item_type, bool is_placeholder, 390 ItemType item_type, bool is_placeholder,
440 bool is_list) 391 bool is_list)
441 : BaseElement(parent), 392 : BaseElement(parent),
442 ow_(this->parent()->ow_), 393 ow_(this->parent()->ow_),
443 any_(), 394 any_(),
444 item_type_(item_type), 395 item_type_(item_type),
445 is_placeholder_(is_placeholder), 396 is_placeholder_(is_placeholder),
446 is_list_(is_list) { 397 is_list_(is_list) {
447 if (item_type == ANY) { 398 if (item_type == ANY) {
448 any_.reset(new AnyWriter(ow_)); 399 any_.reset(new AnyWriter(ow_));
449 } 400 }
450 if (item_type == MAP) {
451 map_keys_.reset(new hash_set<string>);
452 }
453 } 401 }
454 402
455 bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent( 403 bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent(
456 StringPiece map_key) { 404 StringPiece map_key) {
457 return InsertIfNotPresent(map_keys_.get(), map_key.ToString()); 405 return InsertIfNotPresent(&map_keys_, map_key.ToString());
458 } 406 }
459 407
460 ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( 408 ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject(
461 StringPiece name) { 409 StringPiece name) {
462 if (invalid_depth() > 0) { 410 if (invalid_depth() > 0) {
463 IncrementInvalidDepth(); 411 IncrementInvalidDepth();
464 return this; 412 return this;
465 } 413 }
466 414
467 // Starting the root message. Create the root Item and return. 415 // Starting the root message. Create the root Item and return.
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 "Invalid struct data type. Only number, string, boolean or " 852 "Invalid struct data type. Only number, string, boolean or "
905 "null values are supported."); 853 "null values are supported.");
906 } 854 }
907 } 855 }
908 ow->ProtoWriter::RenderDataPiece(struct_field_name, data); 856 ow->ProtoWriter::RenderDataPiece(struct_field_name, data);
909 return Status::OK; 857 return Status::OK;
910 } 858 }
911 859
912 Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, 860 Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
913 const DataPiece& data) { 861 const DataPiece& data) {
914 if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
915 if (data.type() != DataPiece::TYPE_STRING) { 862 if (data.type() != DataPiece::TYPE_STRING) {
916 return Status(INVALID_ARGUMENT, 863 return Status(INVALID_ARGUMENT,
917 StrCat("Invalid data type for timestamp, value is ", 864 StrCat("Invalid data type for timestamp, value is ",
918 data.ValueAsStringOrDefault(""))); 865 data.ValueAsStringOrDefault("")));
919 } 866 }
920 867
921 StringPiece value(data.str()); 868 StringPiece value(data.str());
922 869
923 int64 seconds; 870 int64 seconds;
924 int32 nanos; 871 int32 nanos;
(...skipping 10 matching lines...) Expand all
935 882
936 static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, 883 static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow,
937 StringPiece path) { 884 StringPiece path) {
938 ow->ProtoWriter::RenderDataPiece( 885 ow->ProtoWriter::RenderDataPiece(
939 "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); 886 "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true));
940 return Status::OK; 887 return Status::OK;
941 } 888 }
942 889
943 Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, 890 Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
944 const DataPiece& data) { 891 const DataPiece& data) {
945 if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
946 if (data.type() != DataPiece::TYPE_STRING) { 892 if (data.type() != DataPiece::TYPE_STRING) {
947 return Status(INVALID_ARGUMENT, 893 return Status(INVALID_ARGUMENT,
948 StrCat("Invalid data type for field mask, value is ", 894 StrCat("Invalid data type for field mask, value is ",
949 data.ValueAsStringOrDefault(""))); 895 data.ValueAsStringOrDefault("")));
950 } 896 }
951 897
952 // TODO(tsun): figure out how to do proto descriptor based snake case 898 // TODO(tsun): figure out how to do proto descriptor based snake case
953 // conversions as much as possible. Because ToSnakeCase sometimes returns the 899 // conversions as much as possible. Because ToSnakeCase sometimes returns the
954 // wrong value. 900 // wrong value.
955 google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > call back( 901 google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > call back(
956 NewPermanentCallback(&RenderOneFieldPath, ow)); 902 ::google::protobuf::internal::NewPermanentCallback(&RenderOneFieldPath, ow ));
957 return DecodeCompactFieldMaskPaths(data.str(), callback.get()); 903 return DecodeCompactFieldMaskPaths(data.str(), callback.get());
958 } 904 }
959 905
960 Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, 906 Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
961 const DataPiece& data) { 907 const DataPiece& data) {
962 if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
963 if (data.type() != DataPiece::TYPE_STRING) { 908 if (data.type() != DataPiece::TYPE_STRING) {
964 return Status(INVALID_ARGUMENT, 909 return Status(INVALID_ARGUMENT,
965 StrCat("Invalid data type for duration, value is ", 910 StrCat("Invalid data type for duration, value is ",
966 data.ValueAsStringOrDefault(""))); 911 data.ValueAsStringOrDefault("")));
967 } 912 }
968 913
969 StringPiece value(data.str()); 914 StringPiece value(data.str());
970 915
971 if (!value.ends_with("s")) { 916 if (!value.ends_with("s")) {
972 return Status(INVALID_ARGUMENT, 917 return Status(INVALID_ARGUMENT,
(...skipping 29 matching lines...) Expand all
1002 return Status(INVALID_ARGUMENT, "Duration value exceeds limits"); 947 return Status(INVALID_ARGUMENT, "Duration value exceeds limits");
1003 } 948 }
1004 949
1005 ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); 950 ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
1006 ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); 951 ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
1007 return Status::OK; 952 return Status::OK;
1008 } 953 }
1009 954
1010 Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow, 955 Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow,
1011 const DataPiece& data) { 956 const DataPiece& data) {
1012 if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
1013 ow->ProtoWriter::RenderDataPiece("value", data); 957 ow->ProtoWriter::RenderDataPiece("value", data);
1014 return Status::OK; 958 return Status::OK;
1015 } 959 }
1016 960
1017 ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( 961 ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece(
1018 StringPiece name, const DataPiece& data) { 962 StringPiece name, const DataPiece& data) {
1019 Status status; 963 Status status;
1020 if (invalid_depth() > 0) return this; 964 if (invalid_depth() > 0) return this;
1021 965
1022 if (current_ == NULL) { 966 if (current_ == NULL) {
(...skipping 26 matching lines...) Expand all
1049 if (current_->IsMap()) { 993 if (current_->IsMap()) {
1050 if (!ValidMapKey(name)) return this; 994 if (!ValidMapKey(name)) return this;
1051 995
1052 // Render an item in repeated map list. 996 // Render an item in repeated map list.
1053 // { "key": "<name>", "value": 997 // { "key": "<name>", "value":
1054 Push("", Item::MESSAGE, false, false); 998 Push("", Item::MESSAGE, false, false);
1055 ProtoWriter::RenderDataPiece("key", 999 ProtoWriter::RenderDataPiece("key",
1056 DataPiece(name, use_strict_base64_decoding())); 1000 DataPiece(name, use_strict_base64_decoding()));
1057 field = Lookup("value"); 1001 field = Lookup("value");
1058 if (field == NULL) { 1002 if (field == NULL) {
1059 Pop();
1060 GOOGLE_LOG(DFATAL) << "Map does not have a value field."; 1003 GOOGLE_LOG(DFATAL) << "Map does not have a value field.";
1061 return this; 1004 return this;
1062 } 1005 }
1063 1006
1064 const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); 1007 const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
1065 if (type_renderer != NULL) { 1008 if (type_renderer != NULL) {
1066 // Map's value type is a special type. Render it like a message: 1009 // Map's value type is a special type. Render it like a message:
1067 // "value": { 1010 // "value": {
1068 // ... Render special type ... 1011 // ... Render special type ...
1069 // } 1012 // }
(...skipping 20 matching lines...) Expand all
1090 Pop(); 1033 Pop();
1091 return this; 1034 return this;
1092 } 1035 }
1093 1036
1094 field = Lookup(name); 1037 field = Lookup(name);
1095 if (field == NULL) return this; 1038 if (field == NULL) return this;
1096 1039
1097 // Check if the field is of special type. Render it accordingly if so. 1040 // Check if the field is of special type. Render it accordingly if so.
1098 const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); 1041 const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
1099 if (type_renderer != NULL) { 1042 if (type_renderer != NULL) {
1100 // Pass through null value only for google.protobuf.Value. For other 1043 Push(name, Item::MESSAGE, false, false);
1101 // types we ignore null value just like for regular field types. 1044 status = (*type_renderer)(this, data);
1102 if (data.type() != DataPiece::TYPE_NULL || 1045 if (!status.ok()) {
1103 field->type_url() == kStructValueTypeUrl) { 1046 InvalidValue(field->type_url(),
1104 Push(name, Item::MESSAGE, false, false); 1047 StrCat("Field '", name, "', ", status.error_message()));
1105 status = (*type_renderer)(this, data);
1106 if (!status.ok()) {
1107 InvalidValue(field->type_url(),
1108 StrCat("Field '", name, "', ", status.error_message()));
1109 }
1110 Pop();
1111 } 1048 }
1049 Pop();
1112 return this; 1050 return this;
1113 } 1051 }
1114 1052
1115 // If we are rendering explicit null values and the backend proto field is 1053 // If we are rendering explicit null values and the backend proto field is
1116 // not of the google.protobuf.NullType type, we do nothing. 1054 // not of the google.protobuf.NullType type, we do nothing.
1117 if (data.type() == DataPiece::TYPE_NULL && 1055 if (data.type() == DataPiece::TYPE_NULL &&
1118 field->type_url() != kStructNullValueTypeUrl) { 1056 field->type_url() != kStructNullValueTypeUrl) {
1119 return this; 1057 return this;
1120 } 1058 }
1121 1059
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 field.kind() != google::protobuf::Field_Kind_TYPE_MESSAGE || 1171 field.kind() != google::protobuf::Field_Kind_TYPE_MESSAGE ||
1234 field.cardinality() != 1172 field.cardinality() !=
1235 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) { 1173 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
1236 return false; 1174 return false;
1237 } 1175 }
1238 const google::protobuf::Type* field_type = 1176 const google::protobuf::Type* field_type =
1239 typeinfo()->GetTypeByTypeUrl(field.type_url()); 1177 typeinfo()->GetTypeByTypeUrl(field.type_url());
1240 1178
1241 // TODO(xiaofeng): Unify option names. 1179 // TODO(xiaofeng): Unify option names.
1242 return GetBoolOptionOrDefault(field_type->options(), 1180 return GetBoolOptionOrDefault(field_type->options(),
1243 "google.protobuf.MessageOptions.map_entry", 1181 "google.protobuf.MessageOptions.map_entry", fals e) ||
1244 false) || 1182 GetBoolOptionOrDefault(field_type->options(), "map_entry", false);
1245 GetBoolOptionOrDefault(field_type->options(), "map_entry", false) ||
1246 GetBoolOptionOrDefault(field_type->options(),
1247 "proto2.MessageOptions.map_entry", false);
1248 } 1183 }
1249 1184
1250 bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) { 1185 bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) {
1251 return GetTypeWithoutUrl(field.type_url()) == kAnyType; 1186 return GetTypeWithoutUrl(field.type_url()) == kAnyType;
1252 } 1187 }
1253 1188
1254 bool ProtoStreamObjectWriter::IsStruct(const google::protobuf::Field& field) { 1189 bool ProtoStreamObjectWriter::IsStruct(const google::protobuf::Field& field) {
1255 return GetTypeWithoutUrl(field.type_url()) == kStructType; 1190 return GetTypeWithoutUrl(field.type_url()) == kStructType;
1256 } 1191 }
1257 1192
1258 bool ProtoStreamObjectWriter::IsStructValue( 1193 bool ProtoStreamObjectWriter::IsStructValue(
1259 const google::protobuf::Field& field) { 1194 const google::protobuf::Field& field) {
1260 return GetTypeWithoutUrl(field.type_url()) == kStructValueType; 1195 return GetTypeWithoutUrl(field.type_url()) == kStructValueType;
1261 } 1196 }
1262 1197
1263 bool ProtoStreamObjectWriter::IsStructListValue( 1198 bool ProtoStreamObjectWriter::IsStructListValue(
1264 const google::protobuf::Field& field) { 1199 const google::protobuf::Field& field) {
1265 return GetTypeWithoutUrl(field.type_url()) == kStructListValueType; 1200 return GetTypeWithoutUrl(field.type_url()) == kStructListValueType;
1266 } 1201 }
1267 1202
1268 } // namespace converter 1203 } // namespace converter
1269 } // namespace util 1204 } // namespace util
1270 } // namespace protobuf 1205 } // namespace protobuf
1271 } // namespace google 1206 } // namespace google
1272
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698