protostream_objectwriter.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
32 
33 #include <functional>
34 #include <stack>
35 #include <unordered_map>
36 #include <unordered_set>
37 
46 
47 
50 
51 
52 #include <google/protobuf/port_def.inc>
53 
54 namespace google {
55 namespace protobuf {
56 namespace util {
57 namespace converter {
58 
59 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
60 using std::placeholders::_1;
61 using util::Status;
62 using util::StatusOr;
64 
65 
68  strings::ByteSink* output, ErrorListener* listener,
70  : ProtoWriter(type_resolver, type, output, listener),
71  master_type_(type),
72  current_(nullptr),
73  options_(options) {
78 }
79 
81  const TypeInfo* typeinfo, const google::protobuf::Type& type,
82  strings::ByteSink* output, ErrorListener* listener,
84  : ProtoWriter(typeinfo, type, output, listener),
85  master_type_(type),
86  current_(nullptr),
87  options_(options) {
89  set_use_lower_camel_for_enums(options.use_lower_camel_for_enums);
91 }
92 
94  const TypeInfo* typeinfo, const google::protobuf::Type& type,
95  strings::ByteSink* output, ErrorListener* listener)
96  : ProtoWriter(typeinfo, type, output, listener),
97  master_type_(type),
98  current_(nullptr),
100 
102  if (current_ == nullptr) return;
103  // Cleanup explicitly in order to avoid destructor stack overflow when input
104  // is deeply nested.
105  // Cast to BaseElement to avoid doing additional checks (like missing fields)
106  // during pop().
107  std::unique_ptr<BaseElement> element(
108  static_cast<BaseElement*>(current_.get())->pop<BaseElement>());
109  while (element != nullptr) {
110  element.reset(element->pop<BaseElement>());
111  }
112 }
113 
114 namespace {
115 // Utility method to split a string representation of Timestamp or Duration and
116 // return the parts.
117 void SplitSecondsAndNanos(StringPiece input, StringPiece* seconds,
118  StringPiece* nanos) {
119  size_t idx = input.rfind('.');
120  if (idx != std::string::npos) {
121  *seconds = input.substr(0, idx);
122  *nanos = input.substr(idx + 1);
123  } else {
124  *seconds = input;
125  *nanos = StringPiece();
126  }
127 }
128 
129 Status GetNanosFromStringPiece(StringPiece s_nanos,
130  const char* parse_failure_message,
131  const char* exceeded_limit_message,
132  int32* nanos) {
133  *nanos = 0;
134 
135  // Count the number of leading 0s and consume them.
136  int num_leading_zeros = 0;
137  while (s_nanos.Consume("0")) {
138  num_leading_zeros++;
139  }
140  int32 i_nanos = 0;
141  // 's_nanos' contains fractional seconds -- i.e. 'nanos' is equal to
142  // "0." + s_nanos.ToString() seconds. An int32 is used for the
143  // conversion to 'nanos', rather than a double, so that there is no
144  // loss of precision.
145  if (!s_nanos.empty() && !safe_strto32(s_nanos, &i_nanos)) {
146  return Status(util::error::INVALID_ARGUMENT, parse_failure_message);
147  }
148  if (i_nanos > kNanosPerSecond || i_nanos < 0) {
149  return Status(util::error::INVALID_ARGUMENT, exceeded_limit_message);
150  }
151  // s_nanos should only have digits. No whitespace.
152  if (s_nanos.find_first_not_of("0123456789") != StringPiece::npos) {
153  return Status(util::error::INVALID_ARGUMENT, parse_failure_message);
154  }
155 
156  if (i_nanos > 0) {
157  // 'scale' is the number of digits to the right of the decimal
158  // point in "0." + s_nanos.ToString()
159  int32 scale = num_leading_zeros + s_nanos.size();
160  // 'conversion' converts i_nanos into nanoseconds.
161  // conversion = kNanosPerSecond / static_cast<int32>(std::pow(10, scale))
162  // For efficiency, we precompute the conversion factor.
163  int32 conversion = 0;
164  switch (scale) {
165  case 1:
166  conversion = 100000000;
167  break;
168  case 2:
169  conversion = 10000000;
170  break;
171  case 3:
172  conversion = 1000000;
173  break;
174  case 4:
175  conversion = 100000;
176  break;
177  case 5:
178  conversion = 10000;
179  break;
180  case 6:
181  conversion = 1000;
182  break;
183  case 7:
184  conversion = 100;
185  break;
186  case 8:
187  conversion = 10;
188  break;
189  case 9:
190  conversion = 1;
191  break;
192  default:
194  exceeded_limit_message);
195  }
196  *nanos = i_nanos * conversion;
197  }
198 
199  return Status();
200 }
201 
202 } // namespace
203 
205  : parent_(parent),
206  ow_(),
207  invalid_(false),
208  data_(),
209  output_(&data_),
210  depth_(0),
211  is_well_known_type_(false),
212  well_known_type_render_(nullptr) {}
213 
215 
217  ++depth_;
218  // If an object writer is absent, that means we have not called StartAny()
219  // before reaching here, which happens when we have data before the "@type"
220  // field.
221  if (ow_ == nullptr) {
222  // Save data before the "@type" field for later replay.
223  uninterpreted_events_.push_back(Event(Event::START_OBJECT, name));
224  } else if (is_well_known_type_ && depth_ == 1) {
225  // For well-known types, the only other field besides "@type" should be a
226  // "value" field.
227  if (name != "value" && !invalid_) {
228  parent_->InvalidValue("Any",
229  "Expect a \"value\" field for well-known types.");
230  invalid_ = true;
231  }
232  ow_->StartObject("");
233  } else {
234  // Forward the call to the child writer if:
235  // 1. the type is not a well-known type.
236  // 2. or, we are in a nested Any, Struct, or Value object.
237  ow_->StartObject(name);
238  }
239 }
240 
242  --depth_;
243  if (ow_ == nullptr) {
244  if (depth_ >= 0) {
245  // Save data before the "@type" field for later replay.
246  uninterpreted_events_.push_back(Event(Event::END_OBJECT));
247  }
248  } else if (depth_ >= 0 || !is_well_known_type_) {
249  // As long as depth_ >= 0, we know we haven't reached the end of Any.
250  // Propagate these EndObject() calls to the contained ow_. For regular
251  // message types, we propagate the end of Any as well.
252  ow_->EndObject();
253  }
254  // A negative depth_ implies that we have reached the end of Any
255  // object. Now we write out its contents.
256  if (depth_ < 0) {
257  WriteAny();
258  return false;
259  }
260  return true;
261 }
262 
264  ++depth_;
265  if (ow_ == nullptr) {
266  // Save data before the "@type" field for later replay.
267  uninterpreted_events_.push_back(Event(Event::START_LIST, name));
268  } else if (is_well_known_type_ && depth_ == 1) {
269  if (name != "value" && !invalid_) {
270  parent_->InvalidValue("Any",
271  "Expect a \"value\" field for well-known types.");
272  invalid_ = true;
273  }
274  ow_->StartList("");
275  } else {
276  ow_->StartList(name);
277  }
278 }
279 
281  --depth_;
282  if (depth_ < 0) {
283  GOOGLE_LOG(DFATAL) << "Mismatched EndList found, should not be possible";
284  depth_ = 0;
285  }
286  if (ow_ == nullptr) {
287  // Save data before the "@type" field for later replay.
288  uninterpreted_events_.push_back(Event(Event::END_LIST));
289  } else {
290  ow_->EndList();
291  }
292 }
293 
295  StringPiece name, const DataPiece& value) {
296  // Start an Any only at depth_ 0. Other RenderDataPiece calls with "@type"
297  // should go to the contained ow_ as they indicate nested Anys.
298  if (depth_ == 0 && ow_ == nullptr && name == "@type") {
299  StartAny(value);
300  } else if (ow_ == nullptr) {
301  // Save data before the "@type" field.
302  uninterpreted_events_.push_back(Event(name, value));
303  } else if (depth_ == 0 && is_well_known_type_) {
304  if (name != "value" && !invalid_) {
305  parent_->InvalidValue("Any",
306  "Expect a \"value\" field for well-known types.");
307  invalid_ = true;
308  }
309  if (well_known_type_render_ == nullptr) {
310  // Only Any and Struct don't have a special type render but both of
311  // them expect a JSON object (i.e., a StartObject() call).
312  if (value.type() != DataPiece::TYPE_NULL && !invalid_) {
313  parent_->InvalidValue("Any", "Expect a JSON object.");
314  invalid_ = true;
315  }
316  } else {
317  ow_->ProtoWriter::StartObject("");
318  Status status = (*well_known_type_render_)(ow_.get(), value);
319  if (!status.ok()) ow_->InvalidValue("Any", status.message());
320  ow_->ProtoWriter::EndObject();
321  }
322  } else {
323  ow_->RenderDataPiece(name, value);
324  }
325 }
326 
328  // Figure out the type url. This is a copy-paste from WriteString but we also
329  // need the value, so we can't just call through to that.
330  if (value.type() == DataPiece::TYPE_STRING) {
331  type_url_ = std::string(value.str());
332  } else {
333  StatusOr<std::string> s = value.ToString();
334  if (!s.ok()) {
335  parent_->InvalidValue("String", s.status().message());
336  invalid_ = true;
337  return;
338  }
339  type_url_ = s.ValueOrDie();
340  }
341  // Resolve the type url, and report an error if we failed to resolve it.
343  parent_->typeinfo()->ResolveTypeUrl(type_url_);
344  if (!resolved_type.ok()) {
345  parent_->InvalidValue("Any", resolved_type.status().message());
346  invalid_ = true;
347  return;
348  }
349  // At this point, type is never null.
350  const google::protobuf::Type* type = resolved_type.ValueOrDie();
351 
352  well_known_type_render_ = FindTypeRenderer(type_url_);
353  if (well_known_type_render_ != nullptr ||
354  // Explicitly list Any and Struct here because they don't have a
355  // custom renderer.
356  type->name() == kAnyType || type->name() == kStructType) {
357  is_well_known_type_ = true;
358  }
359 
360  // Create our object writer and initialize it with the first StartObject
361  // call.
362  ow_.reset(new ProtoStreamObjectWriter(parent_->typeinfo(), *type, &output_,
363  parent_->listener(),
364  parent_->options_));
365 
366  // Don't call StartObject() for well-known types yet. Depending on the
367  // type of actual data, we may not need to call StartObject(). For
368  // example:
369  // {
370  // "@type": "type.googleapis.com/google.protobuf.Value",
371  // "value": [1, 2, 3],
372  // }
373  // With the above JSON representation, we will only call StartList() on the
374  // contained ow_.
375  if (!is_well_known_type_) {
376  ow_->StartObject("");
377  }
378 
379  // Now we know the proto type and can interpret all data fields we gathered
380  // before the "@type" field.
381  for (int i = 0; i < uninterpreted_events_.size(); ++i) {
382  uninterpreted_events_[i].Replay(this);
383  }
384 }
385 
387  if (ow_ == nullptr) {
388  if (uninterpreted_events_.empty()) {
389  // We never got any content, so just return immediately, which is
390  // equivalent to writing an empty Any.
391  return;
392  } else {
393  // There are uninterpreted data, but we never got a "@type" field.
394  if (!invalid_) {
395  parent_->InvalidValue("Any",
396  StrCat("Missing @type for any field in ",
397  parent_->master_type_.name()));
398  invalid_ = true;
399  }
400  return;
401  }
402  }
403  // Render the type_url and value fields directly to the stream.
404  // type_url has tag 1 and value has tag 2.
405  WireFormatLite::WriteString(1, type_url_, parent_->stream());
406  if (!data_.empty()) {
407  WireFormatLite::WriteBytes(2, data_, parent_->stream());
408  }
409 }
410 
412  AnyWriter* writer) const {
413  switch (type_) {
414  case START_OBJECT:
415  writer->StartObject(name_);
416  break;
417  case END_OBJECT:
418  writer->EndObject();
419  break;
420  case START_LIST:
421  writer->StartList(name_);
422  break;
423  case END_LIST:
424  writer->EndList();
425  break;
426  case RENDER_DATA_PIECE:
427  writer->RenderDataPiece(name_, value_);
428  break;
429  }
430 }
431 
433  // DataPiece only contains a string reference. To make sure the referenced
434  // string value stays valid, we make a copy of the string value and update
435  // DataPiece to reference our own copy.
436  if (value_.type() == DataPiece::TYPE_STRING) {
437  StrAppend(&value_storage_, value_.str());
438  value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding());
439  } else if (value_.type() == DataPiece::TYPE_BYTES) {
440  value_storage_ = value_.ToBytes().ValueOrDie();
441  value_ =
442  DataPiece(value_storage_, true, value_.use_strict_base64_decoding());
443  }
444 }
445 
447  ItemType item_type, bool is_placeholder,
448  bool is_list)
449  : BaseElement(nullptr),
450  ow_(enclosing),
451  any_(),
452  item_type_(item_type),
453  is_placeholder_(is_placeholder),
454  is_list_(is_list) {
455  if (item_type_ == ANY) {
456  any_.reset(new AnyWriter(ow_));
457  }
458  if (item_type == MAP) {
459  map_keys_.reset(new std::unordered_set<std::string>);
460  }
461 }
462 
464  ItemType item_type, bool is_placeholder,
465  bool is_list)
466  : BaseElement(parent),
467  ow_(this->parent()->ow_),
468  any_(),
469  item_type_(item_type),
470  is_placeholder_(is_placeholder),
471  is_list_(is_list) {
472  if (item_type == ANY) {
473  any_.reset(new AnyWriter(ow_));
474  }
475  if (item_type == MAP) {
476  map_keys_.reset(new std::unordered_set<std::string>);
477  }
478 }
479 
481  StringPiece map_key) {
482  return InsertIfNotPresent(map_keys_.get(), std::string(map_key));
483 }
484 
486  StringPiece name) {
487  if (invalid_depth() > 0) {
489  return this;
490  }
491 
492  // Starting the root message. Create the root Item and return.
493  // ANY message type does not need special handling, just set the ItemType
494  // to ANY.
495  if (current_ == nullptr) {
497  current_.reset(new Item(
498  this, master_type_.name() == kAnyType ? Item::ANY : Item::MESSAGE,
499  false, false));
500 
501  // If master type is a special type that needs extra values to be written to
502  // stream, we write those values.
503  if (master_type_.name() == kStructType) {
504  // Struct has a map<string, Value> field called "fields".
505  // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
506  // "fields": [
507  Push("fields", Item::MAP, true, true);
508  return this;
509  }
510 
511  if (master_type_.name() == kStructValueType) {
512  // We got a StartObject call with google.protobuf.Value field. The only
513  // object within that type is a struct type. So start a struct.
514  //
515  // The struct field in Value type is named "struct_value"
516  // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
517  // Also start the map field "fields" within the struct.
518  // "struct_value": {
519  // "fields": [
520  Push("struct_value", Item::MESSAGE, true, false);
521  Push("fields", Item::MAP, true, true);
522  return this;
523  }
524 
525  if (master_type_.name() == kStructListValueType) {
527  "Cannot start root message with ListValue.");
528  }
529 
530  return this;
531  }
532 
533  // Send all ANY events to AnyWriter.
534  if (current_->IsAny()) {
535  current_->any()->StartObject(name);
536  return this;
537  }
538 
539  // If we are within a map, we render name as keys and send StartObject to the
540  // value field.
541  if (current_->IsMap()) {
542  if (!ValidMapKey(name)) {
544  return this;
545  }
546 
547  // Map is a repeated field of message type with a "key" and a "value" field.
548  // https://developers.google.com/protocol-buffers/docs/proto3?hl=en#maps
549  // message MapFieldEntry {
550  // key_type key = 1;
551  // value_type value = 2;
552  // }
553  //
554  // repeated MapFieldEntry map_field = N;
555  //
556  // That means, we render the following element within a list (hence no
557  // name):
558  // { "key": "<name>", "value": {
559  Push("", Item::MESSAGE, false, false);
562  Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true,
563  false);
564 
565  // Make sure we are valid so far after starting map fields.
566  if (invalid_depth() > 0) return this;
567 
568  // If top of stack is g.p.Struct type, start the struct the map field within
569  // it.
570  if (element() != nullptr && IsStruct(*element()->parent_field())) {
571  // Render "fields": [
572  Push("fields", Item::MAP, true, true);
573  return this;
574  }
575 
576  // If top of stack is g.p.Value type, start the Struct within it.
577  if (element() != nullptr && IsStructValue(*element()->parent_field())) {
578  // Render
579  // "struct_value": {
580  // "fields": [
581  Push("struct_value", Item::MESSAGE, true, false);
582  Push("fields", Item::MAP, true, true);
583  }
584  return this;
585  }
586 
587  const google::protobuf::Field* field = BeginNamed(name, false);
588  if (field == nullptr) return this;
589 
590  if (IsStruct(*field)) {
591  // Start a struct object.
592  // Render
593  // "<name>": {
594  // "fields": {
595  Push(name, Item::MESSAGE, false, false);
596  Push("fields", Item::MAP, true, true);
597  return this;
598  }
599 
600  if (IsStructValue(*field)) {
601  // We got a StartObject call with google.protobuf.Value field. The only
602  // object within that type is a struct type. So start a struct.
603  // Render
604  // "<name>": {
605  // "struct_value": {
606  // "fields": {
607  Push(name, Item::MESSAGE, false, false);
608  Push("struct_value", Item::MESSAGE, true, false);
609  Push("fields", Item::MAP, true, true);
610  return this;
611  }
612 
613  if (IsMap(*field)) {
614  // Begin a map. A map is triggered by a StartObject() call if the current
615  // field has a map type.
616  // A map type is always repeated, hence set is_list to true.
617  // Render
618  // "<name>": [
619  Push(name, Item::MAP, false, true);
620  return this;
621  }
622 
623  // A regular message type. Pass it directly to ProtoWriter.
624  // Render
625  // "<name>": {
626  Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
627  return this;
628 }
629 
631  if (invalid_depth() > 0) {
633  return this;
634  }
635 
636  if (current_ == nullptr) return this;
637 
638  if (current_->IsAny()) {
639  if (current_->any()->EndObject()) return this;
640  }
641 
642  Pop();
643 
644  return this;
645 }
646 
648  StringPiece name) {
649  if (invalid_depth() > 0) {
651  return this;
652  }
653 
654  // Since we cannot have a top-level repeated item in protobuf, the only way
655  // this is valid is if we start a special type google.protobuf.ListValue or
656  // google.protobuf.Value.
657  if (current_ == nullptr) {
658  if (!name.empty()) {
659  InvalidName(name, "Root element should not be named.");
661  return this;
662  }
663 
664  // If master type is a special type that needs extra values to be written to
665  // stream, we write those values.
666  if (master_type_.name() == kStructValueType) {
667  // We got a StartList with google.protobuf.Value master type. This means
668  // we have to start the "list_value" within google.protobuf.Value.
669  //
670  // See
671  // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
672  //
673  // Render
674  // "<name>": {
675  // "list_value": {
676  // "values": [ // Start this list.
678  current_.reset(new Item(this, Item::MESSAGE, false, false));
679  Push("list_value", Item::MESSAGE, true, false);
680  Push("values", Item::MESSAGE, true, true);
681  return this;
682  }
683 
684  if (master_type_.name() == kStructListValueType) {
685  // We got a StartList with google.protobuf.ListValue master type. This
686  // means we have to start the "values" within google.protobuf.ListValue.
687  //
688  // Render
689  // "<name>": {
690  // "values": [ // Start this list.
692  current_.reset(new Item(this, Item::MESSAGE, false, false));
693  Push("values", Item::MESSAGE, true, true);
694  return this;
695  }
696 
697  // Send the event to ProtoWriter so proper errors can be reported.
698  //
699  // Render a regular list:
700  // "<name>": [
702  current_.reset(new Item(this, Item::MESSAGE, false, true));
703  return this;
704  }
705 
706  if (current_->IsAny()) {
707  current_->any()->StartList(name);
708  return this;
709  }
710 
711  // If the top of stack is a map, we are starting a list value within a map.
712  // Since map does not allow repeated values, this can only happen when the map
713  // value is of a special type that renders a list in JSON. These can be one
714  // of 3 cases:
715  // i. We are rendering a list value within google.protobuf.Struct
716  // ii. We are rendering a list value within google.protobuf.Value
717  // iii. We are rendering a list value with type google.protobuf.ListValue.
718  if (current_->IsMap()) {
719  if (!ValidMapKey(name)) {
721  return this;
722  }
723 
724  // Start the repeated map entry object.
725  // Render
726  // { "key": "<name>", "value": {
727  Push("", Item::MESSAGE, false, false);
730  Push("value", Item::MESSAGE, true, false);
731 
732  // Make sure we are valid after pushing all above items.
733  if (invalid_depth() > 0) return this;
734 
735  // case i and ii above. Start "list_value" field within g.p.Value
736  if (element() != nullptr && element()->parent_field() != nullptr) {
737  // Render
738  // "list_value": {
739  // "values": [ // Start this list
740  if (IsStructValue(*element()->parent_field())) {
741  Push("list_value", Item::MESSAGE, true, false);
742  Push("values", Item::MESSAGE, true, true);
743  return this;
744  }
745 
746  // Render
747  // "values": [
748  if (IsStructListValue(*element()->parent_field())) {
749  // case iii above. Bind directly to g.p.ListValue
750  Push("values", Item::MESSAGE, true, true);
751  return this;
752  }
753  }
754 
755  // Report an error.
756  InvalidValue("Map", StrCat("Cannot have repeated items ('", name,
757  "') within a map."));
758  return this;
759  }
760 
761  // When name is empty and stack is not empty, we are rendering an item within
762  // a list.
763  if (name.empty()) {
764  if (element() != nullptr && element()->parent_field() != nullptr) {
765  if (IsStructValue(*element()->parent_field())) {
766  // Since it is g.p.Value, we bind directly to the list_value.
767  // Render
768  // { // g.p.Value item within the list
769  // "list_value": {
770  // "values": [
771  Push("", Item::MESSAGE, false, false);
772  Push("list_value", Item::MESSAGE, true, false);
773  Push("values", Item::MESSAGE, true, true);
774  return this;
775  }
776 
777  if (IsStructListValue(*element()->parent_field())) {
778  // Since it is g.p.ListValue, we bind to it directly.
779  // Render
780  // { // g.p.ListValue item within the list
781  // "values": [
782  Push("", Item::MESSAGE, false, false);
783  Push("values", Item::MESSAGE, true, true);
784  return this;
785  }
786  }
787 
788  // Pass the event to underlying ProtoWriter.
789  Push(name, Item::MESSAGE, false, true);
790  return this;
791  }
792 
793  // name is not empty
795  if (field == nullptr) {
797  return this;
798  }
799 
800  if (IsStructValue(*field)) {
801  // If g.p.Value is repeated, start that list. Otherwise, start the
802  // "list_value" within it.
803  if (IsRepeated(*field)) {
804  // Render it just like a regular repeated field.
805  // "<name>": [
806  Push(name, Item::MESSAGE, false, true);
807  return this;
808  }
809 
810  // Start the "list_value" field.
811  // Render
812  // "<name>": {
813  // "list_value": {
814  // "values": [
815  Push(name, Item::MESSAGE, false, false);
816  Push("list_value", Item::MESSAGE, true, false);
817  Push("values", Item::MESSAGE, true, true);
818  return this;
819  }
820 
821  if (IsStructListValue(*field)) {
822  // If g.p.ListValue is repeated, start that list. Otherwise, start the
823  // "values" within it.
824  if (IsRepeated(*field)) {
825  // Render it just like a regular repeated field.
826  // "<name>": [
827  Push(name, Item::MESSAGE, false, true);
828  return this;
829  }
830 
831  // Start the "values" field within g.p.ListValue.
832  // Render
833  // "<name>": {
834  // "values": [
835  Push(name, Item::MESSAGE, false, false);
836  Push("values", Item::MESSAGE, true, true);
837  return this;
838  }
839 
840  // If we are here, the field should be repeated. Report an error otherwise.
841  if (!IsRepeated(*field)) {
843  InvalidName(name, "Proto field is not repeating, cannot start list.");
844  return this;
845  }
846 
847  if (IsMap(*field)) {
848  InvalidValue("Map", StrCat("Cannot bind a list to map for field '",
849  name, "'."));
851  return this;
852  }
853 
854  // Pass the event to ProtoWriter.
855  // Render
856  // "<name>": [
857  Push(name, Item::MESSAGE, false, true);
858  return this;
859 }
860 
862  if (invalid_depth() > 0) {
864  return this;
865  }
866 
867  if (current_ == nullptr) return this;
868 
869  if (current_->IsAny()) {
870  current_->any()->EndList();
871  return this;
872  }
873 
874  Pop();
875  return this;
876 }
877 
879  const DataPiece& data) {
880  std::string struct_field_name;
881  switch (data.type()) {
882  // Our JSON parser parses numbers as either int64, uint64, or double.
883  case DataPiece::TYPE_INT64: {
884  // If the option to treat integers as strings is set, then render them as
885  // strings. Otherwise, fallback to rendering them as double.
887  StatusOr<int64> int_value = data.ToInt64();
888  if (int_value.ok()) {
889  ow->ProtoWriter::RenderDataPiece(
890  "string_value",
891  DataPiece(StrCat(int_value.ValueOrDie()), true));
892  return Status();
893  }
894  }
895  struct_field_name = "number_value";
896  break;
897  }
898  case DataPiece::TYPE_UINT64: {
899  // If the option to treat integers as strings is set, then render them as
900  // strings. Otherwise, fallback to rendering them as double.
902  StatusOr<uint64> int_value = data.ToUint64();
903  if (int_value.ok()) {
904  ow->ProtoWriter::RenderDataPiece(
905  "string_value",
906  DataPiece(StrCat(int_value.ValueOrDie()), true));
907  return Status();
908  }
909  }
910  struct_field_name = "number_value";
911  break;
912  }
913  case DataPiece::TYPE_DOUBLE: {
915  StatusOr<double> double_value = data.ToDouble();
916  if (double_value.ok()) {
917  ow->ProtoWriter::RenderDataPiece(
918  "string_value",
919  DataPiece(SimpleDtoa(double_value.ValueOrDie()), true));
920  return Status();
921  }
922  }
923  struct_field_name = "number_value";
924  break;
925  }
926  case DataPiece::TYPE_STRING: {
927  struct_field_name = "string_value";
928  break;
929  }
930  case DataPiece::TYPE_BOOL: {
931  struct_field_name = "bool_value";
932  break;
933  }
934  case DataPiece::TYPE_NULL: {
935  struct_field_name = "null_value";
936  break;
937  }
938  default: {
940  "Invalid struct data type. Only number, string, boolean or "
941  "null values are supported.");
942  }
943  }
944  ow->ProtoWriter::RenderDataPiece(struct_field_name, data);
945  return Status();
946 }
947 
949  const DataPiece& data) {
950  if (data.type() == DataPiece::TYPE_NULL) return Status();
951  if (data.type() != DataPiece::TYPE_STRING) {
953  StrCat("Invalid data type for timestamp, value is ",
954  data.ValueAsStringOrDefault("")));
955  }
956 
957  StringPiece value(data.str());
958 
959  int64 seconds;
960  int32 nanos;
961  if (!::google::protobuf::internal::ParseTime(value.ToString(), &seconds,
962  &nanos)) {
963  return Status(INVALID_ARGUMENT, StrCat("Invalid time format: ", value));
964  }
965 
966 
967  ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
968  ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
969  return Status();
970 }
971 
973  StringPiece path) {
974  ow->ProtoWriter::RenderDataPiece(
975  "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true));
976  return Status();
977 }
978 
980  const DataPiece& data) {
981  if (data.type() == DataPiece::TYPE_NULL) return Status();
982  if (data.type() != DataPiece::TYPE_STRING) {
984  StrCat("Invalid data type for field mask, value is ",
985  data.ValueAsStringOrDefault("")));
986  }
987 
988  // TODO(tsun): figure out how to do proto descriptor based snake case
989  // conversions as much as possible. Because ToSnakeCase sometimes returns the
990  // wrong value.
991  return DecodeCompactFieldMaskPaths(data.str(),
992  std::bind(&RenderOneFieldPath, ow, _1));
993 }
994 
996  const DataPiece& data) {
997  if (data.type() == DataPiece::TYPE_NULL) return Status();
998  if (data.type() != DataPiece::TYPE_STRING) {
1000  StrCat("Invalid data type for duration, value is ",
1001  data.ValueAsStringOrDefault("")));
1002  }
1003 
1004  StringPiece value(data.str());
1005 
1006  if (!HasSuffixString(value, "s")) {
1008  "Illegal duration format; duration must end with 's'");
1009  }
1010  value = value.substr(0, value.size() - 1);
1011  int sign = 1;
1012  if (HasPrefixString(value, "-")) {
1013  sign = -1;
1014  value = value.substr(1);
1015  }
1016 
1017  StringPiece s_secs, s_nanos;
1018  SplitSecondsAndNanos(value, &s_secs, &s_nanos);
1019  uint64 unsigned_seconds;
1020  if (!safe_strtou64(s_secs, &unsigned_seconds)) {
1022  "Invalid duration format, failed to parse seconds");
1023  }
1024 
1025  int32 nanos = 0;
1026  Status nanos_status = GetNanosFromStringPiece(
1027  s_nanos, "Invalid duration format, failed to parse nano seconds",
1028  "Duration value exceeds limits", &nanos);
1029  if (!nanos_status.ok()) {
1030  return nanos_status;
1031  }
1032  nanos = sign * nanos;
1033 
1034  int64 seconds = sign * unsigned_seconds;
1035  if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds ||
1036  nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
1038  "Duration value exceeds limits");
1039  }
1040 
1041  ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
1042  ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
1043  return Status();
1044 }
1045 
1047  const DataPiece& data) {
1048  if (data.type() == DataPiece::TYPE_NULL) return Status();
1049  ow->ProtoWriter::RenderDataPiece("value", data);
1050  return Status();
1051 }
1052 
1054  StringPiece name, const DataPiece& data) {
1055  Status status;
1056  if (invalid_depth() > 0) return this;
1057 
1058  if (current_ == nullptr) {
1059  const TypeRenderer* type_renderer =
1061  if (type_renderer == nullptr) {
1062  InvalidName(name, "Root element must be a message.");
1063  return this;
1064  }
1065  // Render the special type.
1066  // "<name>": {
1067  // ... Render special type ...
1068  // }
1070  status = (*type_renderer)(this, data);
1071  if (!status.ok()) {
1072  InvalidValue(master_type_.name(),
1073  StrCat("Field '", name, "', ", status.message()));
1074  }
1076  return this;
1077  }
1078 
1079  if (current_->IsAny()) {
1080  current_->any()->RenderDataPiece(name, data);
1081  return this;
1082  }
1083 
1084  const google::protobuf::Field* field = nullptr;
1085  if (current_->IsMap()) {
1086  if (!ValidMapKey(name)) return this;
1087 
1088  field = Lookup("value");
1089  if (field == nullptr) {
1090  GOOGLE_LOG(DFATAL) << "Map does not have a value field.";
1091  return this;
1092  }
1093 
1095  // If we are rendering explicit null values and the backend proto field is
1096  // not of the google.protobuf.NullType type, interpret null as absence.
1097  if (data.type() == DataPiece::TYPE_NULL &&
1098  field->type_url() != kStructNullValueTypeUrl) {
1099  return this;
1100  }
1101  }
1102 
1103  // Render an item in repeated map list.
1104  // { "key": "<name>", "value":
1105  Push("", Item::MESSAGE, false, false);
1108 
1109  const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
1110  if (type_renderer != nullptr) {
1111  // Map's value type is a special type. Render it like a message:
1112  // "value": {
1113  // ... Render special type ...
1114  // }
1115  Push("value", Item::MESSAGE, true, false);
1116  status = (*type_renderer)(this, data);
1117  if (!status.ok()) {
1118  InvalidValue(field->type_url(),
1119  StrCat("Field '", name, "', ", status.message()));
1120  }
1121  Pop();
1122  return this;
1123  }
1124 
1125  // If we are rendering explicit null values and the backend proto field is
1126  // not of the google.protobuf.NullType type, we do nothing.
1127  if (data.type() == DataPiece::TYPE_NULL &&
1128  field->type_url() != kStructNullValueTypeUrl) {
1129  Pop();
1130  return this;
1131  }
1132 
1133  // Render the map value as a primitive type.
1135  Pop();
1136  return this;
1137  }
1138 
1139  field = Lookup(name);
1140  if (field == nullptr) return this;
1141 
1142  // Check if the field is of special type. Render it accordingly if so.
1143  const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
1144  if (type_renderer != nullptr) {
1145  // Pass through null value only for google.protobuf.Value. For other
1146  // types we ignore null value just like for regular field types.
1147  if (data.type() != DataPiece::TYPE_NULL ||
1148  field->type_url() == kStructValueTypeUrl) {
1149  Push(name, Item::MESSAGE, false, false);
1150  status = (*type_renderer)(this, data);
1151  if (!status.ok()) {
1152  InvalidValue(field->type_url(),
1153  StrCat("Field '", name, "', ", status.message()));
1154  }
1155  Pop();
1156  }
1157  return this;
1158  }
1159 
1160  // If we are rendering explicit null values and the backend proto field is
1161  // not of the google.protobuf.NullType type, we do nothing.
1162  if (data.type() == DataPiece::TYPE_NULL &&
1163  field->type_url() != kStructNullValueTypeUrl) {
1164  return this;
1165  }
1166 
1168  return this;
1169 }
1170 
1171 // Map of functions that are responsible for rendering well known type
1172 // represented by the key.
1173 std::unordered_map<std::string, ProtoStreamObjectWriter::TypeRenderer>*
1176 
1178  renderers_ = new std::unordered_map<std::string,
1180  (*renderers_)["type.googleapis.com/google.protobuf.Timestamp"] =
1182  (*renderers_)["type.googleapis.com/google.protobuf.Duration"] =
1184  (*renderers_)["type.googleapis.com/google.protobuf.FieldMask"] =
1186  (*renderers_)["type.googleapis.com/google.protobuf.Double"] =
1188  (*renderers_)["type.googleapis.com/google.protobuf.Float"] =
1190  (*renderers_)["type.googleapis.com/google.protobuf.Int64"] =
1192  (*renderers_)["type.googleapis.com/google.protobuf.UInt64"] =
1194  (*renderers_)["type.googleapis.com/google.protobuf.Int32"] =
1196  (*renderers_)["type.googleapis.com/google.protobuf.UInt32"] =
1198  (*renderers_)["type.googleapis.com/google.protobuf.Bool"] =
1200  (*renderers_)["type.googleapis.com/google.protobuf.String"] =
1202  (*renderers_)["type.googleapis.com/google.protobuf.Bytes"] =
1204  (*renderers_)["type.googleapis.com/google.protobuf.DoubleValue"] =
1206  (*renderers_)["type.googleapis.com/google.protobuf.FloatValue"] =
1208  (*renderers_)["type.googleapis.com/google.protobuf.Int64Value"] =
1210  (*renderers_)["type.googleapis.com/google.protobuf.UInt64Value"] =
1212  (*renderers_)["type.googleapis.com/google.protobuf.Int32Value"] =
1214  (*renderers_)["type.googleapis.com/google.protobuf.UInt32Value"] =
1216  (*renderers_)["type.googleapis.com/google.protobuf.BoolValue"] =
1218  (*renderers_)["type.googleapis.com/google.protobuf.StringValue"] =
1220  (*renderers_)["type.googleapis.com/google.protobuf.BytesValue"] =
1222  (*renderers_)["type.googleapis.com/google.protobuf.Value"] =
1225 }
1226 
1229  renderers_ = NULL;
1230 }
1231 
1235  InitRendererMap);
1236  return FindOrNull(*renderers_, type_url);
1237 }
1238 
1240  if (current_ == nullptr) return true;
1241 
1242  if (!current_->InsertMapKeyIfNotPresent(unnormalized_name)) {
1243  listener()->InvalidName(
1244  location(), unnormalized_name,
1245  StrCat("Repeated map key: '", unnormalized_name,
1246  "' is already set."));
1247  return false;
1248  }
1249 
1250  return true;
1251 }
1252 
1254  Item::ItemType item_type,
1255  bool is_placeholder, bool is_list) {
1257 
1258  // invalid_depth == 0 means it is a successful StartObject or StartList.
1259  if (invalid_depth() == 0)
1260  current_.reset(
1261  new Item(current_.release(), item_type, is_placeholder, is_list));
1262 }
1263 
1265  // Pop all placeholder items sending StartObject or StartList events to
1266  // ProtoWriter according to is_list value.
1267  while (current_ != nullptr && current_->is_placeholder()) {
1268  PopOneElement();
1269  }
1270  if (current_ != nullptr) {
1271  PopOneElement();
1272  }
1273 }
1274 
1277  current_.reset(current_->pop<Item>());
1278 }
1279 
1281  if (field.type_url().empty() ||
1283  field.cardinality() !=
1285  return false;
1286  }
1288  typeinfo()->GetTypeByTypeUrl(field.type_url());
1289 
1290  return converter::IsMap(field, *field_type);
1291 }
1292 
1294  return GetTypeWithoutUrl(field.type_url()) == kAnyType;
1295 }
1296 
1298  return GetTypeWithoutUrl(field.type_url()) == kStructType;
1299 }
1300 
1302  const google::protobuf::Field& field) {
1303  return GetTypeWithoutUrl(field.type_url()) == kStructValueType;
1304 }
1305 
1307  const google::protobuf::Field& field) {
1308  return GetTypeWithoutUrl(field.type_url()) == kStructListValueType;
1309 }
1310 
1311 } // namespace converter
1312 } // namespace util
1313 } // namespace protobuf
1314 } // namespace google
google::protobuf::util::converter::ProtoWriter::EndList
ProtoWriter * EndList() override
Definition: proto_writer.cc:525
google::protobuf::util::converter::ProtoWriter::listener
ErrorListener * listener()
Definition: proto_writer.h:135
google::protobuf::util::converter::ProtoStreamObjectWriter::ProtoStreamObjectWriter
ProtoStreamObjectWriter(TypeResolver *type_resolver, const google::protobuf::Type &type, strings::ByteSink *output, ErrorListener *listener, const ProtoStreamObjectWriter::Options &options=ProtoStreamObjectWriter::Options::Defaults())
Definition: protostream_objectwriter.cc:66
google::protobuf::util::converter::ErrorListener::InvalidName
virtual void InvalidName(const LocationTrackerInterface &loc, StringPiece invalid_name, StringPiece message)=0
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::ignore_null_value_map_entry
bool ignore_null_value_map_entry
Definition: protostream_objectwriter.h:98
data_
StringPiece data_
Definition: bytestream_unittest.cc:60
google::protobuf::util::converter::kStructValueTypeUrl
const char kStructValueTypeUrl[]
Definition: constants.h:87
google::protobuf::util::converter::ProtoWriter::StartList
ProtoWriter * StartList(StringPiece name) override
Definition: proto_writer.cc:505
google::protobuf::value
const Descriptor::ReservedRange value
Definition: src/google/protobuf/descriptor.h:1954
map_util.h
google::protobuf::util::converter::ProtoWriter::EndObject
ProtoWriter * EndObject() override
Definition: proto_writer.cc:486
google::protobuf::util::converter::ProtoStreamObjectWriter::EndList
ProtoStreamObjectWriter * EndList() override
Definition: protostream_objectwriter.cc:861
google::protobuf::util::converter::ProtoWriter::location
const LocationTrackerInterface & location()
Definition: proto_writer.h:120
google::protobuf::SimpleDtoa
string SimpleDtoa(double value)
Definition: strutil.cc:1219
wire_format_lite.h
google::protobuf::util::converter::ProtoWriter::element
ProtoElement * element() override
Definition: proto_writer.h:248
google::protobuf::util::converter::ProtoStreamObjectWriter::ValidMapKey
bool ValidMapKey(StringPiece unnormalized_name)
Definition: protostream_objectwriter.cc:1239
google::protobuf::util::converter::kAnyType
const char kAnyType[]
Definition: constants.h:90
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::util::converter::GetTypeWithoutUrl
const StringPiece GetTypeWithoutUrl(StringPiece type_url)
Definition: utility.cc:124
google::protobuf::util::StatusOr::ValueOrDie
const T & ValueOrDie() const
Definition: statusor.h:251
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
google::protobuf::util::converter::DecodeCompactFieldMaskPaths
util::Status DecodeCompactFieldMaskPaths(StringPiece paths, PathSinkCallback path_sink)
Definition: field_mask_utility.cc:108
google::protobuf::safe_strto32
bool safe_strto32(const string &str, int32 *value)
Definition: strutil.cc:1364
field_type
zend_class_entry * field_type
Definition: php/ext/google/protobuf/message.c:2028
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
input
std::string input
Definition: tokenizer_unittest.cc:197
google::protobuf::util::converter::kStructValueType
const char kStructValueType[]
Definition: constants.h:75
s
XmlRpcServer s
google::protobuf::util::StatusOr::status
const Status & status() const
Definition: statusor.h:241
google::protobuf::util::converter::ProtoWriter::InvalidName
void InvalidName(StringPiece unknown_name, StringPiece message)
Definition: proto_writer.cc:440
Field_Kind_TYPE_MESSAGE
@ Field_Kind_TYPE_MESSAGE
Definition: type.pb.h:98
google::protobuf.internal::call_once
void call_once(Args &&... args)
Definition: once.h:45
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::ItemType
ItemType
Definition: protostream_objectwriter.h:257
google::protobuf::util::converter::ProtoWriter::set_ignore_unknown_fields
void set_ignore_unknown_fields(bool ignore_unknown_fields)
Definition: proto_writer.h:139
statusor.h
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent
bool InsertMapKeyIfNotPresent(StringPiece map_key)
Definition: protostream_objectwriter.cc:480
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::WriteAny
void WriteAny()
Definition: protostream_objectwriter.cc:386
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::ANY
@ ANY
Definition: protostream_objectwriter.h:260
google::protobuf::util::converter::ProtoStreamObjectWriter::EndObject
ProtoStreamObjectWriter * EndObject() override
Definition: protostream_objectwriter.cc:630
object_location_tracker.h
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::ow_
ProtoStreamObjectWriter * ow_
Definition: protostream_objectwriter.h:296
google::protobuf::util::converter::ToSnakeCase
std::string ToSnakeCase(StringPiece input)
Definition: utility.cc:293
utility.h
google::protobuf::util::converter::kDurationMaxSeconds
const int64 kDurationMaxSeconds
Definition: constants.h:62
protostream_objectwriter.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::pop
ProtoElement * pop()
Definition: proto_writer.cc:347
google::protobuf::util::converter::kDurationMinSeconds
const int64 kDurationMinSeconds
Definition: constants.h:59
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::Event
Definition: protostream_objectwriter.h:165
google::protobuf::util::converter::TypeInfo::GetTypeByTypeUrl
virtual const google::protobuf::Type * GetTypeByTypeUrl(StringPiece type_url) const =0
idx
static uint32_t idx(tarjan *t, const upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5925
google::protobuf::util::converter::ProtoStreamObjectWriter::FindTypeRenderer
static TypeRenderer * FindTypeRenderer(const std::string &type_url)
Definition: protostream_objectwriter.cc:1233
google::protobuf.internal::OnShutdown
void OnShutdown(void(*func)())
Definition: common.cc:344
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderDuration
static util::Status RenderDuration(ProtoStreamObjectWriter *ow, const DataPiece &value)
Definition: protostream_objectwriter.cc:995
output_
std::string output_
Definition: text_format.cc:1531
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::struct_integers_as_strings
bool struct_integers_as_strings
Definition: protostream_objectwriter.h:79
google::protobuf::util::converter::ProtoWriter::set_use_lower_camel_for_enums
void set_use_lower_camel_for_enums(bool use_lower_camel_for_enums)
Definition: proto_writer.h:149
google::protobuf::util::converter::ProtoStreamObjectWriter::StartObject
ProtoStreamObjectWriter * StartObject(StringPiece name) override
Definition: protostream_objectwriter.cc:485
google::protobuf.internal::WireFormatLite::WriteBytes
static void WriteBytes(int field_number, const std::string &value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:493
google::protobuf::StringPiece::npos
static const size_type npos
Definition: stringpiece.h:350
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::use_lower_camel_for_enums
bool use_lower_camel_for_enums
Definition: protostream_objectwriter.h:91
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderTimestamp
static util::Status RenderTimestamp(ProtoStreamObjectWriter *ow, const DataPiece &value)
Definition: protostream_objectwriter.cc:948
google::protobuf::FindOrNull
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:137
google::protobuf::util::converter::DataPiece::TYPE_BYTES
@ TYPE_BYTES
Definition: datapiece.h:73
google::protobuf::util::converter::GetFullTypeWithUrl
const std::string GetFullTypeWithUrl(StringPiece simple_type)
Definition: utility.cc:136
google::protobuf::util::converter::ProtoWriter::set_case_insensitive_enum_parsing
void set_case_insensitive_enum_parsing(bool case_insensitive_enum_parsing)
Definition: proto_writer.h:153
google::protobuf::util::converter::ProtoWriter::set_ignore_unknown_enum_values
void set_ignore_unknown_enum_values(bool ignore_unknown_enum_values)
Definition: proto_writer.h:145
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::Event::Replay
void Replay(AnyWriter *writer) const
Definition: protostream_objectwriter.cc:411
strutil.h
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::EndList
void EndList()
Definition: protostream_objectwriter.cc:280
google::protobuf.internal::once_flag
std::once_flag once_flag
Definition: once.h:43
google::protobuf::util::TypeResolver
Definition: type_resolver.h:52
path
GLsizei const GLchar ** path
Definition: glcorearb.h:3658
google::protobuf::util::converter::DataPiece::TYPE_NULL
@ TYPE_NULL
Definition: datapiece.h:74
google::protobuf::util::converter::ProtoStreamObjectWriter::master_type_
const google::protobuf::Type & master_type_
Definition: protostream_objectwriter.h:401
google::protobuf::python::repeated_composite_container::Item
static PyObject * Item(PyObject *pself, Py_ssize_t index)
Definition: repeated_composite_container.cc:439
google::protobuf::StringPiece
Definition: stringpiece.h:180
google::protobuf::util::converter::ProtoWriter::DecrementInvalidDepth
void DecrementInvalidDepth()
Definition: proto_writer.h:132
google::protobuf::util::converter::ProtoStreamObjectWriter::IsMap
bool IsMap(const google::protobuf::Field &field)
Definition: protostream_objectwriter.cc:1280
google::protobuf::util::converter::ProtoStreamObjectWriter::DeleteRendererMap
static void DeleteRendererMap()
Definition: protostream_objectwriter.cc:1227
google::protobuf.internal::WireFormatLite::WriteString
static void WriteString(int field_number, const std::string &value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:476
google::protobuf::util::converter::IsMap
bool IsMap(const google::protobuf::Field &field, const google::protobuf::Type &type)
Definition: utility.cc:360
time.h
google::protobuf::util::converter::DataPiece::TYPE_BOOL
@ TYPE_BOOL
Definition: datapiece.h:70
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
google::protobuf::util::converter::TypeInfo
Definition: type_info.h:49
google::protobuf::util::converter::kStructListValueType
const char kStructListValueType[]
Definition: constants.h:78
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::AnyWriter
AnyWriter(ProtoStreamObjectWriter *parent)
Definition: protostream_objectwriter.cc:204
field_mask_utility.h
Field_Cardinality_CARDINALITY_REPEATED
@ Field_Cardinality_CARDINALITY_REPEATED
Definition: type.pb.h:132
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy
void DeepCopy()
Definition: protostream_objectwriter.cc:432
google::protobuf::util::converter::ProtoWriter::IncrementInvalidDepth
void IncrementInvalidDepth()
Definition: proto_writer.h:131
google::protobuf::util::converter::ProtoStreamObjectWriter::Pop
void Pop()
Definition: protostream_objectwriter.cc:1264
google::protobuf::util::converter::DataPiece::TYPE_STRING
@ TYPE_STRING
Definition: datapiece.h:72
google::protobuf::util::converter::ProtoStreamObjectWriter::IsAny
bool IsAny(const google::protobuf::Field &field)
Definition: protostream_objectwriter.cc:1293
google::protobuf.internal::ParseTime
bool ParseTime(const string &value, int64 *seconds, int32 *nanos)
Definition: time.cc:285
name_
string name_
Definition: googletest.cc:182
google::protobuf::util::converter::ProtoStreamObjectWriter::TypeRenderer
util::Status(* TypeRenderer)(ProtoStreamObjectWriter *, const DataPiece &)
Definition: protostream_objectwriter.h:136
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: strutil.h:115
google::protobuf::util::converter::ProtoStreamObjectWriter::StartList
ProtoStreamObjectWriter * StartList(StringPiece name) override
Definition: protostream_objectwriter.cc:647
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::item_type_
ItemType item_type_
Definition: protostream_objectwriter.h:302
google::protobuf::util::converter::ProtoWriter::invalid_depth
int invalid_depth()
Definition: proto_writer.h:133
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::MESSAGE
@ MESSAGE
Definition: protostream_objectwriter.h:258
google::protobuf::util::error::INVALID_ARGUMENT
@ INVALID_ARGUMENT
Definition: status.h:50
google::protobuf::util::converter::ProtoWriter::BeginNamed
const google::protobuf::Field * BeginNamed(StringPiece name, bool is_list)
Definition: proto_writer.cc:723
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderFieldMask
static util::Status RenderFieldMask(ProtoStreamObjectWriter *ow, const DataPiece &value)
Definition: protostream_objectwriter.cc:979
google::protobuf::util::converter::ProtoStreamObjectWriter::renderers_
static std::unordered_map< std::string, TypeRenderer > * renderers_
Definition: protostream_objectwriter.h:397
google::protobuf::util::converter::ProtoWriter::RenderDataPiece
virtual ProtoWriter * RenderDataPiece(StringPiece name, const DataPiece &value)
Definition: proto_writer.cc:534
google::protobuf::util::converter::ProtoWriter
Definition: proto_writer.h:67
google::protobuf::util::converter::ProtoStreamObjectWriter::IsStruct
bool IsStruct(const google::protobuf::Field &field)
Definition: protostream_objectwriter.cc:1297
google::protobuf::util::converter::ProtoStreamObjectWriter::Options
Definition: protostream_objectwriter.h:70
google::protobuf::util::StatusOr
Definition: statusor.h:99
aditof::Status
Status
Status of any operation that the TOF sdk performs.
Definition: status_definitions.h:48
google::protobuf::util::converter::StructuredObjectWriter::BaseElement
Definition: structured_objectwriter.h:68
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::RenderDataPiece
void RenderDataPiece(StringPiece name, const DataPiece &value)
Definition: protostream_objectwriter.cc:294
google::protobuf::util::Status::ok
bool ok() const
Definition: status.h:87
value_
int value_
Definition: gmock-matchers_test.cc:571
Field
struct Field Field
Definition: php/ext/google/protobuf/protobuf.h:638
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::ignore_unknown_fields
bool ignore_unknown_fields
Definition: protostream_objectwriter.h:84
type
GLenum type
Definition: glcorearb.h:2695
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderDataPiece
ProtoStreamObjectWriter * RenderDataPiece(StringPiece name, const DataPiece &data) override
Definition: protostream_objectwriter.cc:1053
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderWrapperType
static util::Status RenderWrapperType(ProtoStreamObjectWriter *ow, const DataPiece &value)
Definition: protostream_objectwriter.cc:1046
google::protobuf::util::converter::ObjectWriter::use_strict_base64_decoding
bool use_strict_base64_decoding() const
Definition: object_writer.h:122
google::protobuf::util::converter::ProtoWriter::typeinfo
const TypeInfo * typeinfo()
Definition: proto_writer.h:137
google::int32
int32_t int32
Definition: sdk/include/aditof/log.h:54
google::protobuf::util::converter::ProtoStreamObjectWriter::IsStructListValue
bool IsStructListValue(const google::protobuf::Field &field)
Definition: protostream_objectwriter.cc:1306
google::protobuf::util::converter::ProtoWriter::output_
strings::ByteSink * output_
Definition: proto_writer.h:350
google::protobuf::util::converter::ProtoStreamObjectWriter::Push
void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder, bool is_list)
Definition: protostream_objectwriter.cc:1253
google::protobuf::util::converter::writer_renderers_init_
PROTOBUF_NAMESPACE_ID::internal::once_flag writer_renderers_init_
Definition: protostream_objectwriter.cc:1175
google::protobuf::util::Status::message
StringPiece message() const
Definition: status.h:99
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::~AnyWriter
~AnyWriter()
Definition: protostream_objectwriter.cc:214
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::ignore_unknown_enum_values
bool ignore_unknown_enum_values
Definition: protostream_objectwriter.h:87
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::any_
std::unique_ptr< AnyWriter > any_
Definition: protostream_objectwriter.h:299
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::StartList
void StartList(StringPiece name)
Definition: protostream_objectwriter.cc:263
constants.h
google::protobuf::util::converter::DataPiece::TYPE_DOUBLE
@ TYPE_DOUBLE
Definition: datapiece.h:68
google::protobuf::util::converter::ProtoStreamObjectWriter
Definition: protostream_objectwriter.h:67
once.h
google::protobuf::util::converter::ConvertFieldMaskPath
std::string ConvertFieldMaskPath(const StringPiece path, ConverterCallback converter)
Definition: field_mask_utility.cc:64
google::protobuf::util::converter::ProtoWriter::StartObject
ProtoWriter * StartObject(StringPiece name) override
Definition: proto_writer.cc:454
google::protobuf::util::Status
Definition: status.h:67
google::protobuf::util::converter::ProtoStreamObjectWriter::RenderStructValue
static util::Status RenderStructValue(ProtoStreamObjectWriter *ow, const DataPiece &value)
Definition: protostream_objectwriter.cc:878
type_resolver
TypeResolver * type_resolver
Definition: conformance_cpp.cc:97
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::MAP
@ MAP
Definition: protostream_objectwriter.h:259
google::protobuf::util::converter::ProtoWriter::IsRepeated
bool IsRepeated(const google::protobuf::Field &field)
Definition: proto_writer.cc:572
Type
struct Type Type
Definition: php/ext/google/protobuf/protobuf.h:664
google::protobuf::util::StatusOr::ok
bool ok() const
Definition: statusor.h:246
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
google::protobuf::util::converter::ProtoStreamObjectWriter::InitRendererMap
static void InitRendererMap()
Definition: protostream_objectwriter.cc:1177
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::StartAny
void StartAny(const DataPiece &value)
Definition: protostream_objectwriter.cc:327
google::protobuf::util::converter::ProtoWriter::InvalidValue
void InvalidValue(StringPiece type_name, StringPiece value)
Definition: proto_writer.cc:445
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::Item
Item(ProtoStreamObjectWriter *enclosing, ItemType item_type, bool is_placeholder, bool is_list)
Definition: protostream_objectwriter.cc:446
google::protobuf::util::converter::kNanosPerSecond
const int32 kNanosPerSecond
Definition: constants.h:65
google::protobuf::HasSuffixString
bool HasSuffixString(const string &str, const string &suffix)
Definition: strutil.h:137
type_url
string * type_url
Definition: conformance_cpp.cc:98
google::protobuf::util::converter::RenderOneFieldPath
static util::Status RenderOneFieldPath(ProtoStreamObjectWriter *ow, StringPiece path)
Definition: protostream_objectwriter.cc:972
google::protobuf::util::converter::ProtoStreamObjectWriter::IsStructValue
bool IsStructValue(const google::protobuf::Field &field)
Definition: protostream_objectwriter.cc:1301
google::protobuf::util::converter::ProtoStreamObjectWriter::Options::case_insensitive_enum_parsing
bool case_insensitive_enum_parsing
Definition: protostream_objectwriter.h:94
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf::util::converter::kStructType
const char kStructType[]
Definition: constants.h:72
google::protobuf::util::converter::DataPiece::TYPE_UINT64
@ TYPE_UINT64
Definition: datapiece.h:67
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::safe_strtou64
bool safe_strtou64(const string &str, uint64 *value)
Definition: strutil.cc:1376
google::protobuf::util::converter::ProtoStreamObjectWriter::Item
Definition: protostream_objectwriter.h:254
google::protobuf::util::converter::DataPiece
Definition: datapiece.h:59
google::protobuf::util::converter::ProtoStreamObjectWriter::Item::map_keys_
std::unique_ptr< std::unordered_set< std::string > > map_keys_
Definition: protostream_objectwriter.h:306
false
#define false
Definition: cJSON.c:70
google::protobuf::util::converter::ProtoStreamObjectWriter::PopOneElement
void PopOneElement()
Definition: protostream_objectwriter.cc:1275
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::StartObject
void StartObject(StringPiece name)
Definition: protostream_objectwriter.cc:216
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter
Definition: protostream_objectwriter.h:140
google::protobuf::util::converter::ProtoStreamObjectWriter::current_
std::unique_ptr< Item > current_
Definition: protostream_objectwriter.h:404
google::protobuf::util::converter::StructuredObjectWriter::BaseElement::pop
ElementType * pop()
Definition: structured_objectwriter.h:77
google::protobuf::util::converter::ProtoStreamObjectWriter::~ProtoStreamObjectWriter
~ProtoStreamObjectWriter() override
Definition: protostream_objectwriter.cc:101
google::protobuf::util::converter::ErrorListener
Definition: error_listener.h:53
google::protobuf::util::converter::kStructNullValueTypeUrl
const char kStructNullValueTypeUrl[]
Definition: constants.h:68
google::protobuf::util::converter::ProtoStreamObjectWriter::options_
const ProtoStreamObjectWriter::Options options_
Definition: protostream_objectwriter.h:407
google::protobuf::InsertIfNotPresent
bool InsertIfNotPresent(Collection *const collection, const typename Collection::value_type &vt)
Definition: map_util.h:321
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::util::converter::DataPiece::TYPE_INT64
@ TYPE_INT64
Definition: datapiece.h:65
google::protobuf::util::converter::ProtoWriter::Lookup
const google::protobuf::Field * Lookup(StringPiece name)
Definition: proto_writer.cc:743
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410
google::protobuf::util::converter::ProtoStreamObjectWriter::AnyWriter::EndObject
bool EndObject()
Definition: protostream_objectwriter.cc:241
google::protobuf::StrAppend
void StrAppend(string *result, const AlphaNum &a)
Definition: strutil.cc:1581


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:58