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 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #include <iostream> 36 #include <stack> 37 #include <google/protobuf/stubs/hash.h> 38 39 #include <google/protobuf/message.h> 40 41 #include <google/protobuf/stubs/logging.h> 42 #include <google/protobuf/stubs/common.h> 43 #include <google/protobuf/stubs/mutex.h> 44 #include <google/protobuf/stubs/once.h> 45 #include <google/protobuf/reflection_internal.h> 46 #include <google/protobuf/io/coded_stream.h> 47 #include <google/protobuf/io/zero_copy_stream_impl.h> 48 #include <google/protobuf/descriptor.pb.h> 49 #include <google/protobuf/map_field.h> 50 #include <google/protobuf/descriptor.h> 51 #include <google/protobuf/generated_message_util.h> 52 #include <google/protobuf/reflection_ops.h> 53 #include <google/protobuf/wire_format.h> 54 #include <google/protobuf/stubs/strutil.h> 55 #include <google/protobuf/stubs/map_util.h> 56 #include <google/protobuf/stubs/singleton.h> 57 #include <google/protobuf/stubs/stl_util.h> 58 59 namespace google { 60 namespace protobuf { 61 62 using internal::WireFormat; 63 using internal::ReflectionOps; 64 65 Message::~Message() {} 66 67 void Message::MergeFrom(const Message& from) { 68 const Descriptor* descriptor = GetDescriptor(); 69 GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) 70 << ": Tried to merge from a message with a different type. " 71 "to: " << descriptor->full_name() << ", " 72 "from: " << from.GetDescriptor()->full_name(); 73 ReflectionOps::Merge(from, this); 74 } 75 76 void Message::CheckTypeAndMergeFrom(const MessageLite& other) { 77 MergeFrom(*down_cast<const Message*>(&other)); 78 } 79 80 void Message::CopyFrom(const Message& from) { 81 const Descriptor* descriptor = GetDescriptor(); 82 GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) 83 << ": Tried to copy from a message with a different type. " 84 "to: " << descriptor->full_name() << ", " 85 "from: " << from.GetDescriptor()->full_name(); 86 ReflectionOps::Copy(from, this); 87 } 88 89 string Message::GetTypeName() const { 90 return GetDescriptor()->full_name(); 91 } 92 93 void Message::Clear() { 94 ReflectionOps::Clear(this); 95 } 96 97 bool Message::IsInitialized() const { 98 return ReflectionOps::IsInitialized(*this); 99 } 100 101 void Message::FindInitializationErrors(vector<string>* errors) const { 102 return ReflectionOps::FindInitializationErrors(*this, "", errors); 103 } 104 105 string Message::InitializationErrorString() const { 106 vector<string> errors; 107 FindInitializationErrors(&errors); 108 return Join(errors, ", "); 109 } 110 111 void Message::CheckInitialized() const { 112 GOOGLE_CHECK(IsInitialized()) 113 << "Message of type \"" << GetDescriptor()->full_name() 114 << "\" is missing required fields: " << InitializationErrorString(); 115 } 116 117 void Message::DiscardUnknownFields() { 118 return ReflectionOps::DiscardUnknownFields(this); 119 } 120 121 bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) { 122 return WireFormat::ParseAndMergePartial(input, this); 123 } 124 125 bool Message::ParseFromFileDescriptor(int file_descriptor) { 126 io::FileInputStream input(file_descriptor); 127 return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; 128 } 129 130 bool Message::ParsePartialFromFileDescriptor(int file_descriptor) { 131 io::FileInputStream input(file_descriptor); 132 return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0; 133 } 134 135 bool Message::ParseFromIstream(istream* input) { 136 io::IstreamInputStream zero_copy_input(input); 137 return ParseFromZeroCopyStream(&zero_copy_input) && input->eof(); 138 } 139 140 bool Message::ParsePartialFromIstream(istream* input) { 141 io::IstreamInputStream zero_copy_input(input); 142 return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof(); 143 } 144 145 146 void Message::SerializeWithCachedSizes( 147 io::CodedOutputStream* output) const { 148 WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); 149 } 150 151 int Message::ByteSize() const { 152 int size = WireFormat::ByteSize(*this); 153 SetCachedSize(size); 154 return size; 155 } 156 157 void Message::SetCachedSize(int /* size */) const { 158 GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name() 159 << "\" implements neither SetCachedSize() nor ByteSize(). " 160 "Must implement one or the other."; 161 } 162 163 int Message::SpaceUsed() const { 164 return GetReflection()->SpaceUsed(*this); 165 } 166 167 bool Message::SerializeToFileDescriptor(int file_descriptor) const { 168 io::FileOutputStream output(file_descriptor); 169 return SerializeToZeroCopyStream(&output); 170 } 171 172 bool Message::SerializePartialToFileDescriptor(int file_descriptor) const { 173 io::FileOutputStream output(file_descriptor); 174 return SerializePartialToZeroCopyStream(&output); 175 } 176 177 bool Message::SerializeToOstream(ostream* output) const { 178 { 179 io::OstreamOutputStream zero_copy_output(output); 180 if (!SerializeToZeroCopyStream(&zero_copy_output)) return false; 181 } 182 return output->good(); 183 } 184 185 bool Message::SerializePartialToOstream(ostream* output) const { 186 io::OstreamOutputStream zero_copy_output(output); 187 return SerializePartialToZeroCopyStream(&zero_copy_output); 188 } 189 190 191 // ============================================================================= 192 // Reflection and associated Template Specializations 193 194 Reflection::~Reflection() {} 195 196 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \ 197 template<> \ 198 const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \ 199 const Message& message, const FieldDescriptor* field) const { \ 200 return *static_cast<RepeatedField<TYPE>* >( \ 201 MutableRawRepeatedField(const_cast<Message*>(&message), \ 202 field, CPPTYPE, CTYPE, NULL)); \ 203 } \ 204 \ 205 template<> \ 206 RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \ 207 Message* message, const FieldDescriptor* field) const { \ 208 return static_cast<RepeatedField<TYPE>* >( \ 209 MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \ 210 } 211 212 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1); 213 HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1); 214 HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1); 215 HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1); 216 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1); 217 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1); 218 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1); 219 220 221 #undef HANDLE_TYPE 222 223 void* Reflection::MutableRawRepeatedString( 224 Message* message, const FieldDescriptor* field, bool is_string) const { 225 return MutableRawRepeatedField(message, field, 226 FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL); 227 } 228 229 230 // Default EnumValue API implementations. Real reflection implementations should 231 // override these. However, there are several legacy implementations that do 232 // not, and cannot easily be changed at the same time as the Reflection API, so 233 // we provide these for now. 234 // TODO: Remove these once all Reflection implementations are updated. 235 int Reflection::GetEnumValue(const Message& message, 236 const FieldDescriptor* field) const { 237 GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API."; 238 return 0; 239 } 240 void Reflection::SetEnumValue(Message* message, 241 const FieldDescriptor* field, 242 int value) const { 243 GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API."; 244 } 245 int Reflection::GetRepeatedEnumValue( 246 const Message& message, 247 const FieldDescriptor* field, int index) const { 248 GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API."; 249 return 0; 250 } 251 void Reflection::SetRepeatedEnumValue(Message* message, 252 const FieldDescriptor* field, int index, 253 int value) const { 254 GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API."; 255 } 256 void Reflection::AddEnumValue(Message* message, 257 const FieldDescriptor* field, 258 int value) const { 259 GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API."; 260 } 261 262 MapIterator Reflection::MapBegin( 263 Message* message, 264 const FieldDescriptor* field) const { 265 GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API."; 266 MapIterator iter(message, field); 267 return iter; 268 } 269 270 MapIterator Reflection::MapEnd( 271 Message* message, 272 const FieldDescriptor* field) const { 273 GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API."; 274 MapIterator iter(message, field); 275 return iter; 276 } 277 278 // ============================================================================= 279 // MessageFactory 280 281 MessageFactory::~MessageFactory() {} 282 283 namespace { 284 285 class GeneratedMessageFactory : public MessageFactory { 286 public: 287 GeneratedMessageFactory(); 288 ~GeneratedMessageFactory(); 289 290 static GeneratedMessageFactory* singleton(); 291 292 typedef void RegistrationFunc(const string&); 293 void RegisterFile(const char* file, RegistrationFunc* registration_func); 294 void RegisterType(const Descriptor* descriptor, const Message* prototype); 295 296 // implements MessageFactory --------------------------------------- 297 const Message* GetPrototype(const Descriptor* type); 298 299 private: 300 // Only written at static init time, so does not require locking. 301 hash_map<const char*, RegistrationFunc*, 302 hash<const char*>, streq> file_map_; 303 304 // Initialized lazily, so requires locking. 305 Mutex mutex_; 306 hash_map<const Descriptor*, const Message*> type_map_; 307 }; 308 309 GeneratedMessageFactory* generated_message_factory_ = NULL; 310 GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_); 311 312 void ShutdownGeneratedMessageFactory() { 313 delete generated_message_factory_; 314 } 315 316 void InitGeneratedMessageFactory() { 317 generated_message_factory_ = new GeneratedMessageFactory; 318 internal::OnShutdown(&ShutdownGeneratedMessageFactory); 319 } 320 321 GeneratedMessageFactory::GeneratedMessageFactory() {} 322 GeneratedMessageFactory::~GeneratedMessageFactory() {} 323 324 GeneratedMessageFactory* GeneratedMessageFactory::singleton() { 325 ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_, 326 &InitGeneratedMessageFactory); 327 return generated_message_factory_; 328 } 329 330 void GeneratedMessageFactory::RegisterFile( 331 const char* file, RegistrationFunc* registration_func) { 332 if (!InsertIfNotPresent(&file_map_, file, registration_func)) { 333 GOOGLE_LOG(FATAL) << "File is already registered: " << file; 334 } 335 } 336 337 void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, 338 const Message* prototype) { 339 GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool()) 340 << "Tried to register a non-generated type with the generated " 341 "type registry."; 342 343 // This should only be called as a result of calling a file registration 344 // function during GetPrototype(), in which case we already have locked 345 // the mutex. 346 mutex_.AssertHeld(); 347 if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) { 348 GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name(); 349 } 350 } 351 352 353 const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { 354 { 355 ReaderMutexLock lock(&mutex_); 356 const Message* result = FindPtrOrNull(type_map_, type); 357 if (result != NULL) return result; 358 } 359 360 // If the type is not in the generated pool, then we can't possibly handle 361 // it. 362 if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL; 363 364 // Apparently the file hasn't been registered yet. Let's do that now. 365 RegistrationFunc* registration_func = 366 FindPtrOrNull(file_map_, type->file()->name().c_str()); 367 if (registration_func == NULL) { 368 GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't " 369 "registered: " << type->file()->name(); 370 return NULL; 371 } 372 373 WriterMutexLock lock(&mutex_); 374 375 // Check if another thread preempted us. 376 const Message* result = FindPtrOrNull(type_map_, type); 377 if (result == NULL) { 378 // Nope. OK, register everything. 379 registration_func(type->file()->name()); 380 // Should be here now. 381 result = FindPtrOrNull(type_map_, type); 382 } 383 384 if (result == NULL) { 385 GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't " 386 << "registered: " << type->full_name(); 387 } 388 389 return result; 390 } 391 392 } // namespace 393 394 MessageFactory* MessageFactory::generated_factory() { 395 return GeneratedMessageFactory::singleton(); 396 } 397 398 void MessageFactory::InternalRegisterGeneratedFile( 399 const char* filename, void (*register_messages)(const string&)) { 400 GeneratedMessageFactory::singleton()->RegisterFile(filename, 401 register_messages); 402 } 403 404 void MessageFactory::InternalRegisterGeneratedMessage( 405 const Descriptor* descriptor, const Message* prototype) { 406 GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype); 407 } 408 409 410 MessageFactory* Reflection::GetMessageFactory() const { 411 GOOGLE_LOG(FATAL) << "Not implemented."; 412 return NULL; 413 } 414 415 void* Reflection::RepeatedFieldData( 416 Message* message, const FieldDescriptor* field, 417 FieldDescriptor::CppType cpp_type, 418 const Descriptor* message_type) const { 419 GOOGLE_LOG(FATAL) << "Not implemented."; 420 return NULL; 421 } 422 423 namespace internal { 424 RepeatedFieldAccessor::~RepeatedFieldAccessor() { 425 } 426 } // namespace internal 427 428 const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor( 429 const FieldDescriptor* field) const { 430 GOOGLE_CHECK(field->is_repeated()); 431 switch (field->cpp_type()) { 432 #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \ 433 case FieldDescriptor::CPPTYPE_ ## TYPE: \ 434 return internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<type> >::get(); 435 HANDLE_PRIMITIVE_TYPE(INT32, int32) 436 HANDLE_PRIMITIVE_TYPE(UINT32, uint32) 437 HANDLE_PRIMITIVE_TYPE(INT64, int64) 438 HANDLE_PRIMITIVE_TYPE(UINT64, uint64) 439 HANDLE_PRIMITIVE_TYPE(FLOAT, float) 440 HANDLE_PRIMITIVE_TYPE(DOUBLE, double) 441 HANDLE_PRIMITIVE_TYPE(BOOL, bool) 442 HANDLE_PRIMITIVE_TYPE(ENUM, int32) 443 #undef HANDLE_PRIMITIVE_TYPE 444 case FieldDescriptor::CPPTYPE_STRING: 445 switch (field->options().ctype()) { 446 default: 447 case FieldOptions::STRING: 448 return internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::get(); 449 } 450 break; 451 case FieldDescriptor::CPPTYPE_MESSAGE: 452 if (field->is_map()) { 453 return internal::Singleton<internal::MapFieldAccessor>::get(); 454 } else { 455 return internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::get(); 456 } 457 } 458 GOOGLE_LOG(FATAL) << "Should not reach here."; 459 return NULL; 460 } 461 462 namespace internal { 463 namespace { 464 void ShutdownRepeatedFieldAccessor() { 465 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int32> >::ShutDown(); 466 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint32> >::ShutDown(); 467 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int64> >::ShutDown(); 468 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint64> >::ShutDown(); 469 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<float> >::ShutDown(); 470 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<double> >::ShutDown(); 471 internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<bool> >::ShutDown(); 472 internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::ShutDown(); 473 internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::ShutDown(); 474 internal::Singleton<internal::MapFieldAccessor>::ShutDown(); 475 } 476 477 struct ShutdownRepeatedFieldRegister { 478 ShutdownRepeatedFieldRegister() { 479 OnShutdown(&ShutdownRepeatedFieldAccessor); 480 } 481 } shutdown_; 482 483 } // namespace 484 } // namespace internal 485 486 namespace internal { 487 template<> 488 #if defined(_MSC_VER) && (_MSC_VER >= 1900) 489 // Note: force noinline to workaround MSVC 2015 compiler bug, issue #240 490 GOOGLE_ATTRIBUTE_NOINLINE 491 #endif 492 Message* GenericTypeHandler<Message>::NewFromPrototype( 493 const Message* prototype, google::protobuf::Arena* arena) { 494 return prototype->New(arena); 495 } 496 template<> 497 #if defined(_MSC_VER) && (_MSC_VER >= 1900) 498 // Note: force noinline to workaround MSVC 2015 compiler bug, issue #240 499 GOOGLE_ATTRIBUTE_NOINLINE 500 #endif 501 google::protobuf::Arena* GenericTypeHandler<Message>::GetArena( 502 Message* value) { 503 return value->GetArena(); 504 } 505 template<> 506 #if defined(_MSC_VER) && (_MSC_VER >= 1900) 507 // Note: force noinline to workaround MSVC 2015 compiler bug, issue #240 508 GOOGLE_ATTRIBUTE_NOINLINE 509 #endif 510 void* GenericTypeHandler<Message>::GetMaybeArenaPointer( 511 Message* value) { 512 return value->GetMaybeArenaPointer(); 513 } 514 } // namespace internal 515 516 } // namespace protobuf 517 } // namespace google 518