protobuf/src/google/protobuf/util/internal/json_objectwriter.h
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 
31 #ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
32 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
33 
34 #include <cstdint>
35 #include <memory>
36 #include <string>
37 
38 #include <google/protobuf/io/coded_stream.h>
39 #include <google/protobuf/util/internal/structured_objectwriter.h>
40 #include <google/protobuf/stubs/bytestream.h>
41 
42 // clang-format off
43 #include <google/protobuf/port_def.inc>
44 // clang-format on
45 
46 namespace google {
47 namespace protobuf {
48 namespace util {
49 namespace converter {
50 
51 
52 // An ObjectWriter implementation that outputs JSON. This ObjectWriter
53 // supports writing a compact form or a pretty printed form.
54 //
55 // Sample usage:
56 // string output;
57 // StringOutputStream* str_stream = new StringOutputStream(&output);
58 // CodedOutputStream* out_stream = new CodedOutputStream(str_stream);
59 // JsonObjectWriter* ow = new JsonObjectWriter(" ", out_stream);
60 // ow->StartObject("")
61 // ->RenderString("name", "value")
62 // ->RenderString("emptystring", string())
63 // ->StartObject("nested")
64 // ->RenderInt64("light", 299792458);
65 // ->RenderDouble("pi", 3.141592653589793);
66 // ->EndObject()
67 // ->StartList("empty")
68 // ->EndList()
69 // ->EndObject();
70 //
71 // And then the output string would become:
72 // {
73 // "name": "value",
74 // "emptystring": "",
75 // "nested": {
76 // "light": "299792458",
77 // "pi": 3.141592653589793
78 // },
79 // "empty": []
80 // }
81 //
82 // JsonObjectWriter does not validate if calls actually result in valid JSON.
83 // For example, passing an empty name when one would be required won't result
84 // in an error, just an invalid output.
85 //
86 // Note that all int64 and uint64 are rendered as strings instead of numbers.
87 // This is because JavaScript parses numbers as 64-bit float thus int64 and
88 // uint64 would lose precision if rendered as numbers.
89 //
90 // JsonObjectWriter is thread-unsafe.
91 class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
92  public:
94  : element_(new Element(/*parent=*/nullptr, /*is_json_object=*/false)),
95  stream_(out),
96  sink_(out),
97  indent_string_(indent_string),
98  indent_char_('\0'),
99  indent_count_(0),
100  use_websafe_base64_for_bytes_(false) {
101  // See if we have a trivial sequence of indent characters.
102  if (!indent_string.empty()) {
103  indent_char_ = indent_string[0];
104  indent_count_ = indent_string.length();
105  for (int i = 1; i < indent_string.length(); i++) {
106  if (indent_char_ != indent_string_[i]) {
107  indent_char_ = '\0';
108  indent_count_ = 0;
109  break;
110  }
111  }
112  }
113  }
114  virtual ~JsonObjectWriter();
115 
116  // ObjectWriter methods.
117  JsonObjectWriter* StartObject(StringPiece name) override;
118  JsonObjectWriter* EndObject() override;
119  JsonObjectWriter* StartList(StringPiece name) override;
120  JsonObjectWriter* EndList() override;
121  JsonObjectWriter* RenderBool(StringPiece name, bool value) override;
122  JsonObjectWriter* RenderInt32(StringPiece name, int32_t value) override;
123  JsonObjectWriter* RenderUint32(StringPiece name,
124  uint32_t value) override;
125  JsonObjectWriter* RenderInt64(StringPiece name, int64_t value) override;
126  JsonObjectWriter* RenderUint64(StringPiece name,
127  uint64_t value) override;
128  JsonObjectWriter* RenderDouble(StringPiece name, double value) override;
129  JsonObjectWriter* RenderFloat(StringPiece name, float value) override;
130  JsonObjectWriter* RenderString(StringPiece name,
131  StringPiece value) override;
132  JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value) override;
133  JsonObjectWriter* RenderNull(StringPiece name) override;
134  virtual JsonObjectWriter* RenderNullAsEmpty(StringPiece name);
135 
137  use_websafe_base64_for_bytes_ = value;
138  }
139 
140  protected:
141  class PROTOBUF_EXPORT Element : public BaseElement {
142  public:
143  Element(Element* parent, bool is_json_object)
144  : BaseElement(parent),
145  is_first_(true),
146  is_json_object_(is_json_object) {}
147 
148  // Called before each field of the Element is to be processed.
149  // Returns true if this is the first call (processing the first field).
150  bool is_first() {
151  if (is_first_) {
152  is_first_ = false;
153  return true;
154  }
155  return false;
156  }
157 
158  // Whether we are currently rendering inside a JSON object (i.e., between
159  // StartObject() and EndObject()).
160  bool is_json_object() const { return is_json_object_; }
161 
162  private:
163  bool is_first_;
164  bool is_json_object_;
165 
167  };
168 
169  Element* element() override { return element_.get(); }
170 
171  private:
172  class PROTOBUF_EXPORT ByteSinkWrapper : public strings::ByteSink {
173  public:
175  ~ByteSinkWrapper() override {}
176 
177  // ByteSink methods.
178  void Append(const char* bytes, size_t n) override {
179  stream_->WriteRaw(bytes, n);
180  }
181 
182  private:
184 
186  };
187 
188  // Renders a simple value as a string. By default all non-string Render
189  // methods convert their argument to a string and call this method. This
190  // method can then be used to render the simple value without escaping it.
192  StringPiece value) {
193  WritePrefix(name);
194  WriteRawString(value);
195  return this;
196  }
197 
198  // Pushes a new JSON array element to the stack.
199  void PushArray() {
200  element_.reset(new Element(element_.release(), /*is_json_object=*/false));
201  }
202 
203  // Pushes a new JSON object element to the stack.
204  void PushObject() {
205  element_.reset(new Element(element_.release(), /*is_json_object=*/true));
206  }
207 
208  // Pops an element off of the stack and deletes the popped element.
209  void Pop() {
210  bool needs_newline = !element_->is_first();
211  element_.reset(element_->pop<Element>());
212  if (needs_newline) NewLine();
213  }
214 
215  // If pretty printing is enabled, this will write a newline to the output,
216  // followed by optional indentation. Otherwise this method is a noop.
217  void NewLine() {
218  if (!indent_string_.empty()) {
219  size_t len = sizeof('\n') + (indent_string_.size() * element()->level());
220 
221  // Take the slow-path if we don't have sufficient characters remaining in
222  // our buffer or we have a non-trivial indent string which would prevent
223  // us from using memset.
224  uint8_t* out = nullptr;
225  if (indent_count_ > 0) {
226  out = stream_->GetDirectBufferForNBytesAndAdvance(len);
227  }
228 
229  if (out != nullptr) {
230  out[0] = '\n';
231  memset(&out[1], indent_char_, len - 1);
232  } else {
233  // Slow path, no contiguous output buffer available.
234  WriteChar('\n');
235  for (int i = 0; i < element()->level(); i++) {
236  stream_->WriteRaw(indent_string_.c_str(), indent_string_.length());
237  }
238  }
239  }
240  }
241 
242  // Writes a prefix. This will write out any pretty printing and
243  // commas that are required, followed by the name and a ':' if
244  // the name is not null.
245  void WritePrefix(StringPiece name);
246 
247  // Writes an individual character to the output.
248  void WriteChar(const char c) { stream_->WriteRaw(&c, sizeof(c)); }
249 
250  // Writes a string to the output.
252  stream_->WriteRaw(s.data(), s.length());
253  }
254 
255  std::unique_ptr<Element> element_;
257  ByteSinkWrapper sink_;
258  const std::string indent_string_;
259 
260  // For the common case of indent being a single character repeated.
263 
264  // Whether to use regular or websafe base64 encoding for byte fields. Defaults
265  // to regular base64 encoding.
266  bool use_websafe_base64_for_bytes_;
267 
269 };
270 
271 } // namespace converter
272 } // namespace util
273 } // namespace protobuf
274 } // namespace google
275 
276 #include <google/protobuf/port_undef.inc>
277 
278 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
google::protobuf::util::converter::JsonObjectWriter::ByteSinkWrapper::Append
void Append(const char *bytes, size_t n) override
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:178
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
google::protobuf::util::converter::JsonObjectWriter::ByteSinkWrapper
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/json_objectwriter.h:152
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
element
static std::function< Slot &(Slot *)> element
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:44
google::protobuf::util::converter::JsonObjectWriter::indent_count_
int indent_count_
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:262
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/macros.h:40
google::protobuf::StringPiece::length
stringpiece_ssize_type length() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.h:249
memset
return memset(p, 0, total)
stream_
std::unique_ptr< grpc::ClientReaderInterface< OrcaLoadReport > > stream_
Definition: orca_service_end2end_test.cc:89
false
#define false
Definition: setup_once.h:323
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::util::converter::JsonObjectWriter::PushObject
void PushObject()
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:204
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
make_cmakelists.converter
converter
Definition: make_cmakelists.py:317
setup.name
name
Definition: setup.py:542
sink_
FormatSinkImpl * sink_
Definition: abseil-cpp/absl/strings/internal/str_format/bind.cc:146
env.new
def new
Definition: env.py:51
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
true
#define true
Definition: setup_once.h:324
google::protobuf::util::converter::JsonObjectWriter::ByteSinkWrapper::ByteSinkWrapper
ByteSinkWrapper(io::CodedOutputStream *stream)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:174
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
google::protobuf::util::converter::JsonObjectWriter::Element::is_json_object
bool is_json_object() const
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:160
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
google::protobuf::util::converter::JsonObjectWriter::Element::is_first
bool is_first()
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:150
google::protobuf::StringPiece::empty
bool empty() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.h:250
google::protobuf::util::converter::JsonObjectWriter::Pop
void Pop()
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:209
google::protobuf::StringPiece
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.h:180
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
google::protobuf::util::converter::JsonObjectWriter::JsonObjectWriter
JsonObjectWriter(StringPiece indent_string, io::CodedOutputStream *out)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:93
google::protobuf::util::converter::JsonObjectWriter::Element::Element
Element(Element *parent, bool is_json_object)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:143
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS
#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/macros.h:45
google::protobuf::util::converter::JsonObjectWriter::NewLine
void NewLine()
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:217
google::protobuf::util::converter::JsonObjectWriter
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/json_objectwriter.h:88
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
google::protobuf::util::converter::JsonObjectWriter::WriteRawString
void WriteRawString(StringPiece s)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:251
google::protobuf::io::CodedOutputStream
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream.h:1044
google::protobuf::util::converter::StructuredObjectWriter::BaseElement
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/structured_objectwriter.h:68
google::protobuf::util::converter::JsonObjectWriter::ByteSinkWrapper::~ByteSinkWrapper
~ByteSinkWrapper() override
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:175
google::protobuf::util::converter::JsonObjectWriter::set_use_websafe_base64_for_bytes
void set_use_websafe_base64_for_bytes(bool value)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:136
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
google::protobuf::util::converter::JsonObjectWriter::PushArray
void PushArray()
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:199
google::protobuf::util::converter::JsonObjectWriter::indent_char_
char indent_char_
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:261
google::protobuf::strings::ByteSink
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/bytestream.h:78
google::protobuf::util::converter::JsonObjectWriter::Element
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/json_objectwriter.h:121
google::protobuf::util::converter::JsonObjectWriter::RenderSimple
JsonObjectWriter * RenderSimple(StringPiece name, StringPiece value)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:191
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
google::protobuf::util::converter::JsonObjectWriter::WriteChar
void WriteChar(const char c)
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:248
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
google::protobuf::util::converter::JsonObjectWriter::element
Element * element() override
Definition: protobuf/src/google/protobuf/util/internal/json_objectwriter.h:169
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:12