• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef GOOGLE_PROTOBUF_JSON_INTERNAL_UNPARSER_TRAITS_H__
9 #define GOOGLE_PROTOBUF_JSON_INTERNAL_UNPARSER_TRAITS_H__
10 
11 #include <algorithm>
12 #include <cfloat>
13 #include <cstdint>
14 #include <memory>
15 #include <sstream>
16 #include <string>
17 #include <type_traits>
18 #include <utility>
19 #include <vector>
20 
21 #include "google/protobuf/type.pb.h"
22 #include "absl/container/flat_hash_map.h"
23 #include "absl/status/status.h"
24 #include "absl/strings/escaping.h"
25 #include "absl/strings/numbers.h"
26 #include "absl/strings/str_format.h"
27 #include "absl/strings/string_view.h"
28 #include "absl/types/optional.h"
29 #include "absl/types/variant.h"
30 #include "google/protobuf/io/coded_stream.h"
31 #include "google/protobuf/json/internal/descriptor_traits.h"
32 #include "google/protobuf/stubs/status_macros.h"
33 
34 // Must be included last.
35 #include "google/protobuf/port_def.inc"
36 
37 namespace google {
38 namespace protobuf {
39 namespace json_internal {
40 // The type traits in this file provide describe how to read from protobuf
41 // representation used by the JSON API, either via proto reflection or via
42 // something ad-hoc for type.proto.
43 
44 // Helper alias templates to avoid needing to write `typename` in function
45 // signatures.
46 template <typename Traits>
47 using Msg = typename Traits::Msg;
48 
49 // Traits for proto2-ish deserialization.
50 struct UnparseProto2Descriptor : Proto2Descriptor {
51   // A message value that fields can be read from.
52   using Msg = Message;
53 
GetDescUnparseProto2Descriptor54   static const Desc& GetDesc(const Msg& msg) { return *msg.GetDescriptor(); }
55 
56   // Appends extension fields to `fields`.
FindAndAppendExtensionsUnparseProto2Descriptor57   static void FindAndAppendExtensions(const Msg& msg,
58                                       std::vector<Field>& fields) {
59     // Note that it is *not* correct to use ListFields for getting a list of
60     // fields to write, because the way that JSON decides to print non-extension
61     // fields is slightly subtle. That logic is handled elsewhere; we're only
62     // here to get extensions.
63     std::vector<Field> all_fields;
64     msg.GetReflection()->ListFields(msg, &all_fields);
65 
66     for (Field field : all_fields) {
67       if (field->is_extension()) {
68         fields.push_back(field);
69       }
70     }
71   }
72 
GetSizeUnparseProto2Descriptor73   static size_t GetSize(Field f, const Msg& msg) {
74     if (f->is_repeated()) {
75       return msg.GetReflection()->FieldSize(msg, f);
76     } else {
77       return msg.GetReflection()->HasField(msg, f) ? 1 : 0;
78     }
79   }
80 
GetFloatUnparseProto2Descriptor81   static absl::StatusOr<float> GetFloat(Field f) {
82     return f->default_value_float();
83   }
84 
GetDoubleUnparseProto2Descriptor85   static absl::StatusOr<double> GetDouble(Field f) {
86     return f->default_value_double();
87   }
88 
GetInt32UnparseProto2Descriptor89   static absl::StatusOr<int32_t> GetInt32(Field f) {
90     return f->default_value_int32();
91   }
92 
GetUInt32UnparseProto2Descriptor93   static absl::StatusOr<uint32_t> GetUInt32(Field f) {
94     return f->default_value_uint32();
95   }
96 
GetInt64UnparseProto2Descriptor97   static absl::StatusOr<int64_t> GetInt64(Field f) {
98     return f->default_value_int64();
99   }
100 
GetUInt64UnparseProto2Descriptor101   static absl::StatusOr<uint64_t> GetUInt64(Field f) {
102     return f->default_value_uint64();
103   }
104 
GetBoolUnparseProto2Descriptor105   static absl::StatusOr<bool> GetBool(Field f) {
106     return f->default_value_bool();
107   }
108 
GetEnumValueUnparseProto2Descriptor109   static absl::StatusOr<int32_t> GetEnumValue(Field f) {
110     return f->default_value_enum()->number();
111   }
112 
GetStringUnparseProto2Descriptor113   static absl::StatusOr<absl::string_view> GetString(Field f,
114                                                      std::string& scratch) {
115     return f->default_value_string();
116   }
117 
GetMessageUnparseProto2Descriptor118   static absl::StatusOr<const Msg*> GetMessage(Field f) {
119     return absl::InternalError("message fields cannot have defaults");
120   }
121 
GetFloatUnparseProto2Descriptor122   static absl::StatusOr<float> GetFloat(Field f, const Msg& msg) {
123     return msg.GetReflection()->GetFloat(msg, f);
124   }
125 
GetDoubleUnparseProto2Descriptor126   static absl::StatusOr<double> GetDouble(Field f, const Msg& msg) {
127     return msg.GetReflection()->GetDouble(msg, f);
128   }
129 
GetInt32UnparseProto2Descriptor130   static absl::StatusOr<int32_t> GetInt32(Field f, const Msg& msg) {
131     return msg.GetReflection()->GetInt32(msg, f);
132   }
133 
GetUInt32UnparseProto2Descriptor134   static absl::StatusOr<uint32_t> GetUInt32(Field f, const Msg& msg) {
135     return msg.GetReflection()->GetUInt32(msg, f);
136   }
137 
GetInt64UnparseProto2Descriptor138   static absl::StatusOr<int64_t> GetInt64(Field f, const Msg& msg) {
139     return msg.GetReflection()->GetInt64(msg, f);
140   }
141 
GetUInt64UnparseProto2Descriptor142   static absl::StatusOr<uint64_t> GetUInt64(Field f, const Msg& msg) {
143     return msg.GetReflection()->GetUInt64(msg, f);
144   }
145 
GetBoolUnparseProto2Descriptor146   static absl::StatusOr<bool> GetBool(Field f, const Msg& msg) {
147     return msg.GetReflection()->GetBool(msg, f);
148   }
149 
GetEnumValueUnparseProto2Descriptor150   static absl::StatusOr<int32_t> GetEnumValue(Field f, const Msg& msg) {
151     return msg.GetReflection()->GetEnumValue(msg, f);
152   }
153 
GetStringUnparseProto2Descriptor154   static absl::StatusOr<absl::string_view> GetString(Field f,
155                                                      std::string& scratch,
156                                                      const Msg& msg) {
157     return msg.GetReflection()->GetStringReference(msg, f, &scratch);
158   }
159 
GetMessageUnparseProto2Descriptor160   static absl::StatusOr<const Msg*> GetMessage(Field f, const Msg& msg) {
161     return &msg.GetReflection()->GetMessage(msg, f);
162   }
163 
GetFloatUnparseProto2Descriptor164   static absl::StatusOr<float> GetFloat(Field f, const Msg& msg, size_t idx) {
165     return msg.GetReflection()->GetRepeatedFloat(msg, f, idx);
166   }
167 
GetDoubleUnparseProto2Descriptor168   static absl::StatusOr<double> GetDouble(Field f, const Msg& msg, size_t idx) {
169     return msg.GetReflection()->GetRepeatedDouble(msg, f, idx);
170   }
171 
GetInt32UnparseProto2Descriptor172   static absl::StatusOr<int32_t> GetInt32(Field f, const Msg& msg, size_t idx) {
173     return msg.GetReflection()->GetRepeatedInt32(msg, f, idx);
174   }
175 
GetUInt32UnparseProto2Descriptor176   static absl::StatusOr<uint32_t> GetUInt32(Field f, const Msg& msg,
177                                             size_t idx) {
178     return msg.GetReflection()->GetRepeatedUInt32(msg, f, idx);
179   }
180 
GetInt64UnparseProto2Descriptor181   static absl::StatusOr<int64_t> GetInt64(Field f, const Msg& msg, size_t idx) {
182     return msg.GetReflection()->GetRepeatedInt64(msg, f, idx);
183   }
184 
GetUInt64UnparseProto2Descriptor185   static absl::StatusOr<uint64_t> GetUInt64(Field f, const Msg& msg,
186                                             size_t idx) {
187     return msg.GetReflection()->GetRepeatedUInt64(msg, f, idx);
188   }
189 
GetBoolUnparseProto2Descriptor190   static absl::StatusOr<bool> GetBool(Field f, const Msg& msg, size_t idx) {
191     return msg.GetReflection()->GetRepeatedBool(msg, f, idx);
192   }
193 
GetEnumValueUnparseProto2Descriptor194   static absl::StatusOr<int32_t> GetEnumValue(Field f, const Msg& msg,
195                                               size_t idx) {
196     return msg.GetReflection()->GetRepeatedEnumValue(msg, f, idx);
197   }
198 
GetStringUnparseProto2Descriptor199   static absl::StatusOr<absl::string_view> GetString(Field f,
200                                                      std::string& scratch,
201                                                      const Msg& msg,
202                                                      size_t idx) {
203     return msg.GetReflection()->GetRepeatedStringReference(msg, f, idx,
204                                                            &scratch);
205   }
206 
GetMessageUnparseProto2Descriptor207   static absl::StatusOr<const Msg*> GetMessage(Field f, const Msg& msg,
208                                                size_t idx) {
209     return &msg.GetReflection()->GetRepeatedMessage(msg, f, idx);
210   }
211 
212   template <typename F>
WithDecodedMessageUnparseProto2Descriptor213   static absl::Status WithDecodedMessage(const Desc& desc,
214                                          absl::string_view data, F body) {
215     DynamicMessageFactory factory;
216     std::unique_ptr<Message> unerased(factory.GetPrototype(&desc)->New());
217     unerased->ParsePartialFromString(data);
218 
219     // Explicitly create a const reference, so that we do not accidentally pass
220     // a mutable reference to `body`.
221     const Msg& ref = *unerased;
222     return body(ref);
223   }
224 };
225 
226 struct UnparseProto3Type : Proto3Type {
227   using Msg = UntypedMessage;
228 
GetDescUnparseProto3Type229   static const Desc& GetDesc(const Msg& msg) { return msg.desc(); }
230 
FindAndAppendExtensionsUnparseProto3Type231   static void FindAndAppendExtensions(const Msg&, std::vector<Field>&) {
232     // type.proto does not support extensions.
233   }
234 
GetSizeUnparseProto3Type235   static size_t GetSize(Field f, const Msg& msg) {
236     return msg.Count(f->proto().number());
237   }
238 
GetFloatUnparseProto3Type239   static absl::StatusOr<float> GetFloat(Field f) {
240     if (f->proto().default_value().empty()) {
241       return 0.0;
242     }
243     float x;
244     if (!absl::SimpleAtof(f->proto().default_value(), &x)) {
245       return absl::InternalError(absl::StrCat(
246           "bad default value in type.proto: ", f->parent().proto().name()));
247     }
248     return x;
249   }
250 
GetDoubleUnparseProto3Type251   static absl::StatusOr<double> GetDouble(Field f) {
252     if (f->proto().default_value().empty()) {
253       return 0.0;
254     }
255     double x;
256     if (!absl::SimpleAtod(f->proto().default_value(), &x)) {
257       return absl::InternalError(absl::StrCat(
258           "bad default value in type.proto: ", f->parent().proto().name()));
259     }
260     return x;
261   }
262 
GetInt32UnparseProto3Type263   static absl::StatusOr<int32_t> GetInt32(Field f) {
264     if (f->proto().default_value().empty()) {
265       return 0;
266     }
267     int32_t x;
268     if (!absl::SimpleAtoi(f->proto().default_value(), &x)) {
269       return absl::InternalError(absl::StrCat(
270           "bad default value in type.proto: ", f->parent().proto().name()));
271     }
272     return x;
273   }
274 
GetUInt32UnparseProto3Type275   static absl::StatusOr<uint32_t> GetUInt32(Field f) {
276     if (f->proto().default_value().empty()) {
277       return 0;
278     }
279     uint32_t x;
280     if (!absl::SimpleAtoi(f->proto().default_value(), &x)) {
281       return absl::InternalError(absl::StrCat(
282           "bad default value in type.proto: ", f->parent().proto().name()));
283     }
284     return x;
285   }
286 
GetInt64UnparseProto3Type287   static absl::StatusOr<int64_t> GetInt64(Field f) {
288     if (f->proto().default_value().empty()) {
289       return 0;
290     }
291     int64_t x;
292     if (!absl::SimpleAtoi(f->proto().default_value(), &x)) {
293       return absl::InternalError(absl::StrCat(
294           "bad default value in type.proto: ", f->parent().proto().name()));
295     }
296     return x;
297   }
298 
GetUInt64UnparseProto3Type299   static absl::StatusOr<uint64_t> GetUInt64(Field f) {
300     if (f->proto().default_value().empty()) {
301       return 0;
302     }
303     uint64_t x;
304     if (!absl::SimpleAtoi(f->proto().default_value(), &x)) {
305       return absl::InternalError(absl::StrCat(
306           "bad default value in type.proto: ", f->parent().proto().name()));
307     }
308     return x;
309   }
310 
GetBoolUnparseProto3Type311   static absl::StatusOr<bool> GetBool(Field f) {
312     if (f->proto().default_value().empty()) {
313       return false;
314     } else if (f->proto().default_value() == "false") {
315       return false;
316     } else if (f->proto().default_value() == "true") {
317       return true;
318     } else {
319       return absl::InternalError(absl::StrCat(
320           "bad default value in type.proto: ", f->parent().proto().name()));
321     }
322   }
323 
GetEnumValueUnparseProto3Type324   static absl::StatusOr<int32_t> GetEnumValue(Field f) {
325     if (f->proto().default_value().empty()) {
326       auto e = f->EnumType();
327       RETURN_IF_ERROR(e.status());
328 
329       return (**e).proto().enumvalue(0).number();
330     }
331     return EnumNumberByName(f, f->proto().default_value(),
332                             /*case_insensitive=*/false);
333   }
334 
GetStringUnparseProto3Type335   static absl::StatusOr<absl::string_view> GetString(Field f,
336                                                      std::string& scratch) {
337     absl::CUnescape(f->proto().default_value(), &scratch);
338     return scratch;
339   }
340 
GetMessageUnparseProto3Type341   static absl::StatusOr<const Msg*> GetMessage(Field f) {
342     return absl::InternalError("message fields cannot have defaults");
343   }
344 
345   static absl::StatusOr<float> GetFloat(Field f, const Msg& msg,
346                                         size_t idx = 0) {
347     return msg.Get<float>(f->proto().number())[idx];
348   }
349 
350   static absl::StatusOr<double> GetDouble(Field f, const Msg& msg,
351                                           size_t idx = 0) {
352     return msg.Get<double>(f->proto().number())[idx];
353   }
354 
355   static absl::StatusOr<int32_t> GetInt32(Field f, const Msg& msg,
356                                           size_t idx = 0) {
357     return msg.Get<int32_t>(f->proto().number())[idx];
358   }
359 
360   static absl::StatusOr<uint32_t> GetUInt32(Field f, const Msg& msg,
361                                             size_t idx = 0) {
362     return msg.Get<uint32_t>(f->proto().number())[idx];
363   }
364 
365   static absl::StatusOr<int64_t> GetInt64(Field f, const Msg& msg,
366                                           size_t idx = 0) {
367     return msg.Get<int64_t>(f->proto().number())[idx];
368   }
369 
370   static absl::StatusOr<uint64_t> GetUInt64(Field f, const Msg& msg,
371                                             size_t idx = 0) {
372     return msg.Get<uint64_t>(f->proto().number())[idx];
373   }
374 
375   static absl::StatusOr<bool> GetBool(Field f, const Msg& msg, size_t idx = 0) {
376     return msg.Get<Msg::Bool>(f->proto().number())[idx] == Msg::kTrue;
377   }
378 
379   static absl::StatusOr<int32_t> GetEnumValue(Field f, const Msg& msg,
380                                               size_t idx = 0) {
381     return msg.Get<int32_t>(f->proto().number())[idx];
382   }
383 
384   static absl::StatusOr<absl::string_view> GetString(Field f,
385                                                      std::string& scratch,
386                                                      const Msg& msg,
387                                                      size_t idx = 0) {
388     return msg.Get<std::string>(f->proto().number())[idx];
389   }
390 
391   static absl::StatusOr<const Msg*> GetMessage(Field f, const Msg& msg,
392                                                size_t idx = 0) {
393     return &msg.Get<Msg>(f->proto().number())[idx];
394   }
395 
396   template <typename F>
WithDecodedMessageUnparseProto3Type397   static absl::Status WithDecodedMessage(const Desc& desc,
398                                          absl::string_view data, F body) {
399     io::CodedInputStream stream(reinterpret_cast<const uint8_t*>(data.data()),
400                                 data.size());
401     auto unerased = Msg::ParseFromStream(&desc, stream);
402     RETURN_IF_ERROR(unerased.status());
403 
404     // Explicitly create a const reference, so that we do not accidentally pass
405     // a mutable reference to `body`.
406     const Msg& ref = *unerased;
407     return body(ref);
408   }
409 };
410 }  // namespace json_internal
411 }  // namespace protobuf
412 }  // namespace google
413 
414 #include "google/protobuf/port_undef.inc"
415 #endif  // GOOGLE_PROTOBUF_JSON_INTERNAL_UNPARSER_TRAITS_H__
416