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