| 319 | |
| 320 | |
| 321 | static bool JsonValueToProtoField(const BUTIL_RAPIDJSON_NAMESPACE::Value& value, |
| 322 | const google::protobuf::FieldDescriptor* field, |
| 323 | google::protobuf::Message* message, |
| 324 | const Json2PbOptions& options, |
| 325 | std::string* err, |
| 326 | int depth) { |
| 327 | if (value.IsNull()) { |
| 328 | if (field->is_required()) { |
| 329 | J2PERROR(err, "Missing required field: %s", butil::EnsureString(field->full_name()).c_str()); |
| 330 | return false; |
| 331 | } |
| 332 | return true; |
| 333 | } |
| 334 | |
| 335 | if (field->is_repeated()) { |
| 336 | if (!value.IsArray()) { |
| 337 | J2PERROR(err, "Invalid value for repeated field: %s", |
| 338 | butil::EnsureString(field->full_name()).c_str()); |
| 339 | return false; |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | const google::protobuf::Reflection* reflection = message->GetReflection(); |
| 344 | switch (field->cpp_type()) { |
| 345 | #define CASE_FIELD_TYPE(cpptype, method, jsontype) \ |
| 346 | case google::protobuf::FieldDescriptor::CPPTYPE_##cpptype: { \ |
| 347 | if (field->is_repeated()) { \ |
| 348 | const BUTIL_RAPIDJSON_NAMESPACE::SizeType size = value.Size(); \ |
| 349 | for (BUTIL_RAPIDJSON_NAMESPACE::SizeType index = 0; index < size; ++index) { \ |
| 350 | const BUTIL_RAPIDJSON_NAMESPACE::Value & item = value[index]; \ |
| 351 | if (TYPE_MATCH == J2PCHECKTYPE(item, cpptype, jsontype)) { \ |
| 352 | reflection->Add##method(message, field, item.Get##jsontype()); \ |
| 353 | } \ |
| 354 | } \ |
| 355 | } else if (TYPE_MATCH == J2PCHECKTYPE(value, cpptype, jsontype)) { \ |
| 356 | reflection->Set##method(message, field, value.Get##jsontype()); \ |
| 357 | } \ |
| 358 | break; \ |
| 359 | } \ |
| 360 | |
| 361 | CASE_FIELD_TYPE(INT32, Int32, Int); |
| 362 | CASE_FIELD_TYPE(UINT32, UInt32, Uint); |
| 363 | CASE_FIELD_TYPE(BOOL, Bool, Bool); |
| 364 | #undef CASE_FIELD_TYPE |
| 365 | |
| 366 | case google::protobuf::FieldDescriptor::CPPTYPE_INT64: |
| 367 | if (field->is_repeated()) { |
| 368 | const BUTIL_RAPIDJSON_NAMESPACE::SizeType size = value.Size(); |
| 369 | for (BUTIL_RAPIDJSON_NAMESPACE::SizeType index = 0; index < size; |
| 370 | ++index) { |
| 371 | const BUTIL_RAPIDJSON_NAMESPACE::Value& item = value[index]; |
| 372 | if (!convert_int64_type(item, true, message, field, reflection, |
| 373 | err)) { |
| 374 | return false; |
| 375 | } |
| 376 | } |
| 377 | } else if (!convert_int64_type(value, false, message, field, reflection, |
| 378 | err)) { |
no test coverage detected