message.cc 18 KB

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