message.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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 "google/protobuf/message.h"
  34. #include <iostream>
  35. #include <stack>
  36. #include "absl/base/casts.h"
  37. #include "absl/container/flat_hash_map.h"
  38. #include "absl/container/flat_hash_set.h"
  39. #include "absl/log/absl_check.h"
  40. #include "absl/log/absl_log.h"
  41. #include "absl/strings/str_join.h"
  42. #include "absl/strings/string_view.h"
  43. #include "absl/synchronization/mutex.h"
  44. #include "google/protobuf/descriptor.h"
  45. #include "google/protobuf/descriptor.pb.h"
  46. #include "google/protobuf/generated_message_reflection.h"
  47. #include "google/protobuf/generated_message_tctable_impl.h"
  48. #include "google/protobuf/generated_message_util.h"
  49. #include "google/protobuf/io/coded_stream.h"
  50. #include "google/protobuf/io/zero_copy_stream_impl.h"
  51. #include "google/protobuf/map_field.h"
  52. #include "google/protobuf/map_field_inl.h"
  53. #include "google/protobuf/parse_context.h"
  54. #include "google/protobuf/reflection_internal.h"
  55. #include "google/protobuf/reflection_ops.h"
  56. #include "google/protobuf/unknown_field_set.h"
  57. #include "google/protobuf/wire_format.h"
  58. #include "google/protobuf/wire_format_lite.h"
  59. // Must be included last.
  60. #include "google/protobuf/port_def.inc"
  61. namespace google {
  62. namespace protobuf {
  63. namespace internal {
  64. // TODO(gerbens) make this factorized better. This should not have to hop
  65. // to reflection. Currently uses GeneratedMessageReflection and thus is
  66. // defined in generated_message_reflection.cc
  67. void RegisterFileLevelMetadata(const DescriptorTable* descriptor_table);
  68. } // namespace internal
  69. using internal::DownCast;
  70. using internal::ReflectionOps;
  71. using internal::WireFormat;
  72. using internal::WireFormatLite;
  73. void Message::MergeFrom(const Message& from) {
  74. auto* class_to = GetClassData();
  75. auto* class_from = from.GetClassData();
  76. auto* merge_to_from = class_to ? class_to->merge_to_from : nullptr;
  77. if (class_to == nullptr || class_to != class_from) {
  78. merge_to_from = [](Message& to, const Message& from) {
  79. ReflectionOps::Merge(from, &to);
  80. };
  81. }
  82. merge_to_from(*this, from);
  83. }
  84. void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
  85. MergeFrom(*DownCast<const Message*>(&other));
  86. }
  87. void Message::CopyFrom(const Message& from) {
  88. if (&from == this) return;
  89. auto* class_to = GetClassData();
  90. auto* class_from = from.GetClassData();
  91. auto* copy_to_from = class_to ? class_to->copy_to_from : nullptr;
  92. if (class_to == nullptr || class_to != class_from) {
  93. const Descriptor* descriptor = GetDescriptor();
  94. ABSL_CHECK_EQ(from.GetDescriptor(), descriptor)
  95. << ": Tried to copy from a message with a different type. "
  96. "to: "
  97. << descriptor->full_name()
  98. << ", "
  99. "from: "
  100. << from.GetDescriptor()->full_name();
  101. copy_to_from = [](Message& to, const Message& from) {
  102. ReflectionOps::Copy(from, &to);
  103. };
  104. }
  105. copy_to_from(*this, from);
  106. }
  107. void Message::CopyWithSourceCheck(Message& to, const Message& from) {
  108. // Fail if "from" is a descendant of "to" as such copy is not allowed.
  109. ABSL_DCHECK(!internal::IsDescendant(to, from))
  110. << "Source of CopyFrom cannot be a descendant of the target.";
  111. to.Clear();
  112. to.GetClassData()->merge_to_from(to, from);
  113. }
  114. std::string Message::GetTypeName() const {
  115. return GetDescriptor()->full_name();
  116. }
  117. void Message::Clear() { ReflectionOps::Clear(this); }
  118. bool Message::IsInitialized() const {
  119. return ReflectionOps::IsInitialized(*this);
  120. }
  121. void Message::FindInitializationErrors(std::vector<std::string>* errors) const {
  122. return ReflectionOps::FindInitializationErrors(*this, "", errors);
  123. }
  124. std::string Message::InitializationErrorString() const {
  125. std::vector<std::string> errors;
  126. FindInitializationErrors(&errors);
  127. return absl::StrJoin(errors, ", ");
  128. }
  129. void Message::CheckInitialized() const {
  130. ABSL_CHECK(IsInitialized())
  131. << "Message of type \"" << GetDescriptor()->full_name()
  132. << "\" is missing required fields: " << InitializationErrorString();
  133. }
  134. void Message::DiscardUnknownFields() {
  135. return ReflectionOps::DiscardUnknownFields(this);
  136. }
  137. const char* Message::_InternalParse(const char* ptr,
  138. internal::ParseContext* ctx) {
  139. #if defined(PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION)
  140. auto meta = GetMetadata();
  141. ptr = internal::TcParser::ParseLoop(this, ptr, ctx,
  142. meta.reflection->GetTcParseTable());
  143. return ptr;
  144. #else
  145. return WireFormat::_InternalParse(this, ptr, ctx);
  146. #endif
  147. }
  148. uint8_t* Message::_InternalSerialize(uint8_t* target,
  149. io::EpsCopyOutputStream* stream) const {
  150. return WireFormat::_InternalSerialize(*this, target, stream);
  151. }
  152. size_t Message::ByteSizeLong() const {
  153. size_t size = WireFormat::ByteSize(*this);
  154. SetCachedSize(internal::ToCachedSize(size));
  155. return size;
  156. }
  157. void Message::SetCachedSize(int /* size */) const {
  158. ABSL_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
  159. << "\" implements neither SetCachedSize() nor ByteSize(). "
  160. "Must implement one or the other.";
  161. }
  162. size_t Message::ComputeUnknownFieldsSize(
  163. size_t total_size, internal::CachedSize* cached_size) const {
  164. total_size += WireFormat::ComputeUnknownFieldsSize(
  165. _internal_metadata_.unknown_fields<UnknownFieldSet>(
  166. UnknownFieldSet::default_instance));
  167. cached_size->Set(internal::ToCachedSize(total_size));
  168. return total_size;
  169. }
  170. size_t Message::MaybeComputeUnknownFieldsSize(
  171. size_t total_size, internal::CachedSize* cached_size) const {
  172. if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
  173. return ComputeUnknownFieldsSize(total_size, cached_size);
  174. }
  175. cached_size->Set(internal::ToCachedSize(total_size));
  176. return total_size;
  177. }
  178. size_t Message::SpaceUsedLong() const {
  179. return GetReflection()->SpaceUsedLong(*this);
  180. }
  181. uint64_t Message::GetInvariantPerBuild(uint64_t salt) {
  182. return salt;
  183. }
  184. namespace internal {
  185. void* CreateSplitMessageGeneric(Arena* arena, const void* default_split,
  186. size_t size, const void* message,
  187. const void* default_message) {
  188. ABSL_DCHECK_NE(message, default_message);
  189. void* split =
  190. (arena == nullptr) ? ::operator new(size) : arena->AllocateAligned(size);
  191. memcpy(split, default_split, size);
  192. return split;
  193. }
  194. } // namespace internal
  195. // =============================================================================
  196. // MessageFactory
  197. MessageFactory::~MessageFactory() {}
  198. namespace {
  199. class GeneratedMessageFactory final : public MessageFactory {
  200. public:
  201. static GeneratedMessageFactory* singleton();
  202. void RegisterFile(const google::protobuf::internal::DescriptorTable* table);
  203. void RegisterType(const Descriptor* descriptor, const Message* prototype);
  204. // implements MessageFactory ---------------------------------------
  205. const Message* GetPrototype(const Descriptor* type) override;
  206. private:
  207. const Message* FindInTypeMap(const Descriptor* type)
  208. ABSL_SHARED_LOCKS_REQUIRED(mutex_)
  209. {
  210. auto it = type_map_.find(type);
  211. if (it == type_map_.end()) return nullptr;
  212. return it->second;
  213. }
  214. const google::protobuf::internal::DescriptorTable* FindInFileMap(
  215. absl::string_view name) {
  216. auto it = files_.find(name);
  217. if (it == files_.end()) return nullptr;
  218. return *it;
  219. }
  220. struct DescriptorByNameHash {
  221. using is_transparent = void;
  222. size_t operator()(const google::protobuf::internal::DescriptorTable* t) const {
  223. return absl::HashOf(absl::string_view{t->filename});
  224. }
  225. size_t operator()(absl::string_view name) const {
  226. return absl::HashOf(name);
  227. }
  228. };
  229. struct DescriptorByNameEq {
  230. using is_transparent = void;
  231. bool operator()(const google::protobuf::internal::DescriptorTable* lhs,
  232. const google::protobuf::internal::DescriptorTable* rhs) const {
  233. return lhs == rhs || (*this)(lhs->filename, rhs->filename);
  234. }
  235. bool operator()(absl::string_view lhs,
  236. const google::protobuf::internal::DescriptorTable* rhs) const {
  237. return (*this)(lhs, rhs->filename);
  238. }
  239. bool operator()(const google::protobuf::internal::DescriptorTable* lhs,
  240. absl::string_view rhs) const {
  241. return (*this)(lhs->filename, rhs);
  242. }
  243. bool operator()(absl::string_view lhs, absl::string_view rhs) const {
  244. return lhs == rhs;
  245. }
  246. };
  247. // Only written at static init time, so does not require locking.
  248. absl::flat_hash_set<const google::protobuf::internal::DescriptorTable*,
  249. DescriptorByNameHash, DescriptorByNameEq>
  250. files_;
  251. absl::Mutex mutex_;
  252. absl::flat_hash_map<const Descriptor*, const Message*> type_map_
  253. ABSL_GUARDED_BY(mutex_);
  254. };
  255. GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
  256. static auto instance =
  257. internal::OnShutdownDelete(new GeneratedMessageFactory);
  258. return instance;
  259. }
  260. void GeneratedMessageFactory::RegisterFile(
  261. const google::protobuf::internal::DescriptorTable* table) {
  262. if (!files_.insert(table).second) {
  263. ABSL_LOG(FATAL) << "File is already registered: " << table->filename;
  264. }
  265. }
  266. void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
  267. const Message* prototype) {
  268. ABSL_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
  269. << "Tried to register a non-generated type with the generated "
  270. "type registry.";
  271. // This should only be called as a result of calling a file registration
  272. // function during GetPrototype(), in which case we already have locked
  273. // the mutex.
  274. mutex_.AssertHeld();
  275. if (!type_map_.try_emplace(descriptor, prototype).second) {
  276. ABSL_DLOG(FATAL) << "Type is already registered: "
  277. << descriptor->full_name();
  278. }
  279. }
  280. const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
  281. {
  282. absl::ReaderMutexLock lock(&mutex_);
  283. const Message* result = FindInTypeMap(type);
  284. if (result != nullptr) return result;
  285. }
  286. // If the type is not in the generated pool, then we can't possibly handle
  287. // it.
  288. if (type->file()->pool() != DescriptorPool::generated_pool()) return nullptr;
  289. // Apparently the file hasn't been registered yet. Let's do that now.
  290. const internal::DescriptorTable* registration_data =
  291. FindInFileMap(type->file()->name());
  292. if (registration_data == nullptr) {
  293. ABSL_DLOG(FATAL) << "File appears to be in generated pool but wasn't "
  294. "registered: "
  295. << type->file()->name();
  296. return nullptr;
  297. }
  298. absl::WriterMutexLock lock(&mutex_);
  299. // Check if another thread preempted us.
  300. const Message* result = FindInTypeMap(type);
  301. if (result == nullptr) {
  302. // Nope. OK, register everything.
  303. internal::RegisterFileLevelMetadata(registration_data);
  304. // Should be here now.
  305. result = FindInTypeMap(type);
  306. }
  307. if (result == nullptr) {
  308. ABSL_DLOG(FATAL) << "Type appears to be in generated pool but wasn't "
  309. << "registered: " << type->full_name();
  310. }
  311. return result;
  312. }
  313. } // namespace
  314. MessageFactory* MessageFactory::generated_factory() {
  315. return GeneratedMessageFactory::singleton();
  316. }
  317. void MessageFactory::InternalRegisterGeneratedFile(
  318. const google::protobuf::internal::DescriptorTable* table) {
  319. GeneratedMessageFactory::singleton()->RegisterFile(table);
  320. }
  321. void MessageFactory::InternalRegisterGeneratedMessage(
  322. const Descriptor* descriptor, const Message* prototype) {
  323. GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
  324. }
  325. namespace {
  326. template <typename T>
  327. T* GetSingleton() {
  328. static T singleton;
  329. return &singleton;
  330. }
  331. } // namespace
  332. const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor(
  333. const FieldDescriptor* field) const {
  334. ABSL_CHECK(field->is_repeated());
  335. switch (field->cpp_type()) {
  336. #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \
  337. case FieldDescriptor::CPPTYPE_##TYPE: \
  338. return GetSingleton<internal::RepeatedFieldPrimitiveAccessor<type> >();
  339. HANDLE_PRIMITIVE_TYPE(INT32, int32_t)
  340. HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t)
  341. HANDLE_PRIMITIVE_TYPE(INT64, int64_t)
  342. HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t)
  343. HANDLE_PRIMITIVE_TYPE(FLOAT, float)
  344. HANDLE_PRIMITIVE_TYPE(DOUBLE, double)
  345. HANDLE_PRIMITIVE_TYPE(BOOL, bool)
  346. HANDLE_PRIMITIVE_TYPE(ENUM, int32_t)
  347. #undef HANDLE_PRIMITIVE_TYPE
  348. case FieldDescriptor::CPPTYPE_STRING:
  349. switch (field->options().ctype()) {
  350. default:
  351. case FieldOptions::STRING:
  352. return GetSingleton<internal::RepeatedPtrFieldStringAccessor>();
  353. }
  354. break;
  355. case FieldDescriptor::CPPTYPE_MESSAGE:
  356. if (field->is_map()) {
  357. return GetSingleton<internal::MapFieldAccessor>();
  358. } else {
  359. return GetSingleton<internal::RepeatedPtrFieldMessageAccessor>();
  360. }
  361. }
  362. ABSL_LOG(FATAL) << "Should not reach here.";
  363. return nullptr;
  364. }
  365. namespace internal {
  366. template <>
  367. #if defined(_MSC_VER) && (_MSC_VER >= 1800)
  368. // Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
  369. // #240
  370. PROTOBUF_NOINLINE
  371. #endif
  372. Message*
  373. GenericTypeHandler<Message>::NewFromPrototype(const Message* prototype,
  374. Arena* arena) {
  375. return prototype->New(arena);
  376. }
  377. template <>
  378. #if defined(_MSC_VER) && (_MSC_VER >= 1800)
  379. // Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
  380. // #240
  381. PROTOBUF_NOINLINE
  382. #endif
  383. Arena*
  384. GenericTypeHandler<Message>::GetOwningArena(Message* value) {
  385. return value->GetOwningArena();
  386. }
  387. template void InternalMetadata::DoClear<UnknownFieldSet>();
  388. template void InternalMetadata::DoMergeFrom<UnknownFieldSet>(
  389. const UnknownFieldSet& other);
  390. template void InternalMetadata::DoSwap<UnknownFieldSet>(UnknownFieldSet* other);
  391. template Arena* InternalMetadata::DeleteOutOfLineHelper<UnknownFieldSet>();
  392. template UnknownFieldSet*
  393. InternalMetadata::mutable_unknown_fields_slow<UnknownFieldSet>();
  394. } // namespace internal
  395. } // namespace protobuf
  396. } // namespace google
  397. #include "google/protobuf/port_undef.inc"