诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

738 lines
26 KiB

  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 <unordered_map>
  36. #include <google/protobuf/generated_message_reflection.h>
  37. #include <google/protobuf/message.h>
  38. #include <google/protobuf/stubs/casts.h>
  39. #include <google/protobuf/stubs/logging.h>
  40. #include <google/protobuf/stubs/common.h>
  41. #include <google/protobuf/descriptor.pb.h>
  42. #include <google/protobuf/parse_context.h>
  43. #include <google/protobuf/reflection_internal.h>
  44. #include <google/protobuf/io/coded_stream.h>
  45. #include <google/protobuf/io/zero_copy_stream_impl.h>
  46. #include <google/protobuf/descriptor.h>
  47. #include <google/protobuf/generated_message_util.h>
  48. #include <google/protobuf/map_field.h>
  49. #include <google/protobuf/map_field_inl.h>
  50. #include <google/protobuf/reflection_ops.h>
  51. #include <google/protobuf/unknown_field_set.h>
  52. #include <google/protobuf/wire_format.h>
  53. #include <google/protobuf/wire_format_lite.h>
  54. #include <google/protobuf/stubs/strutil.h>
  55. #include <google/protobuf/stubs/map_util.h>
  56. #include <google/protobuf/stubs/stl_util.h>
  57. #include <google/protobuf/stubs/hash.h>
  58. #include <google/protobuf/port_def.inc>
  59. namespace google {
  60. namespace protobuf {
  61. namespace internal {
  62. // TODO(gerbens) make this factorized better. This should not have to hop
  63. // to reflection. Currently uses GeneratedMessageReflection and thus is
  64. // defined in generated_message_reflection.cc
  65. void RegisterFileLevelMetadata(const DescriptorTable* descriptor_table);
  66. } // namespace internal
  67. using internal::ReflectionOps;
  68. using internal::WireFormat;
  69. using internal::WireFormatLite;
  70. void Message::MergeFrom(const Message& from) {
  71. const Descriptor* descriptor = GetDescriptor();
  72. GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
  73. << ": Tried to merge from a message with a different type. "
  74. "to: "
  75. << descriptor->full_name()
  76. << ", "
  77. "from: "
  78. << from.GetDescriptor()->full_name();
  79. ReflectionOps::Merge(from, this);
  80. }
  81. void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
  82. MergeFrom(*down_cast<const Message*>(&other));
  83. }
  84. void Message::CopyFrom(const Message& from) {
  85. const Descriptor* descriptor = GetDescriptor();
  86. GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
  87. << ": Tried to copy from a message with a different type. "
  88. "to: "
  89. << descriptor->full_name()
  90. << ", "
  91. "from: "
  92. << from.GetDescriptor()->full_name();
  93. ReflectionOps::Copy(from, this);
  94. }
  95. std::string Message::GetTypeName() const {
  96. return GetDescriptor()->full_name();
  97. }
  98. void Message::Clear() { ReflectionOps::Clear(this); }
  99. bool Message::IsInitialized() const {
  100. return ReflectionOps::IsInitialized(*this);
  101. }
  102. void Message::FindInitializationErrors(std::vector<std::string>* errors) const {
  103. return ReflectionOps::FindInitializationErrors(*this, "", errors);
  104. }
  105. std::string Message::InitializationErrorString() const {
  106. std::vector<std::string> errors;
  107. FindInitializationErrors(&errors);
  108. return Join(errors, ", ");
  109. }
  110. void Message::CheckInitialized() const {
  111. GOOGLE_CHECK(IsInitialized()) << "Message of type \"" << GetDescriptor()->full_name()
  112. << "\" is missing required fields: "
  113. << InitializationErrorString();
  114. }
  115. void Message::DiscardUnknownFields() {
  116. return ReflectionOps::DiscardUnknownFields(this);
  117. }
  118. namespace internal {
  119. class ReflectionAccessor {
  120. public:
  121. static void* GetOffset(void* msg, const google::protobuf::FieldDescriptor* f,
  122. const google::protobuf::Reflection* r) {
  123. return static_cast<char*>(msg) + r->schema_.GetFieldOffset(f);
  124. }
  125. static void* GetRepeatedEnum(const Reflection* reflection,
  126. const FieldDescriptor* field, Message* msg) {
  127. return reflection->MutableRawRepeatedField(
  128. msg, field, FieldDescriptor::CPPTYPE_ENUM, 0, nullptr);
  129. }
  130. static InternalMetadataWithArena* MutableInternalMetadataWithArena(
  131. const Reflection* reflection, Message* msg) {
  132. return reflection->MutableInternalMetadataWithArena(msg);
  133. }
  134. };
  135. } // namespace internal
  136. void SetField(uint64 val, const FieldDescriptor* field, Message* msg,
  137. const Reflection* reflection) {
  138. #define STORE_TYPE(CPPTYPE_METHOD) \
  139. do \
  140. if (field->is_repeated()) { \
  141. reflection->Add##CPPTYPE_METHOD(msg, field, value); \
  142. } else { \
  143. reflection->Set##CPPTYPE_METHOD(msg, field, value); \
  144. } \
  145. while (0)
  146. switch (field->type()) {
  147. #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
  148. case FieldDescriptor::TYPE_##TYPE: { \
  149. CPPTYPE value = val; \
  150. STORE_TYPE(CPPTYPE_METHOD); \
  151. break; \
  152. }
  153. // Varints
  154. HANDLE_TYPE(INT32, int32, Int32)
  155. HANDLE_TYPE(INT64, int64, Int64)
  156. HANDLE_TYPE(UINT32, uint32, UInt32)
  157. HANDLE_TYPE(UINT64, uint64, UInt64)
  158. case FieldDescriptor::TYPE_SINT32: {
  159. int32 value = WireFormatLite::ZigZagDecode32(val);
  160. STORE_TYPE(Int32);
  161. break;
  162. }
  163. case FieldDescriptor::TYPE_SINT64: {
  164. int64 value = WireFormatLite::ZigZagDecode64(val);
  165. STORE_TYPE(Int64);
  166. break;
  167. }
  168. HANDLE_TYPE(BOOL, bool, Bool)
  169. // Fixed
  170. HANDLE_TYPE(FIXED32, uint32, UInt32)
  171. HANDLE_TYPE(FIXED64, uint64, UInt64)
  172. HANDLE_TYPE(SFIXED32, int32, Int32)
  173. HANDLE_TYPE(SFIXED64, int64, Int64)
  174. case FieldDescriptor::TYPE_FLOAT: {
  175. float value;
  176. uint32 bit_rep = val;
  177. std::memcpy(&value, &bit_rep, sizeof(value));
  178. STORE_TYPE(Float);
  179. break;
  180. }
  181. case FieldDescriptor::TYPE_DOUBLE: {
  182. double value;
  183. uint64 bit_rep = val;
  184. std::memcpy(&value, &bit_rep, sizeof(value));
  185. STORE_TYPE(Double);
  186. break;
  187. }
  188. case FieldDescriptor::TYPE_ENUM: {
  189. int value = val;
  190. if (field->is_repeated()) {
  191. reflection->AddEnumValue(msg, field, value);
  192. } else {
  193. reflection->SetEnumValue(msg, field, value);
  194. }
  195. break;
  196. }
  197. default:
  198. GOOGLE_LOG(FATAL) << "Error in descriptors, primitve field with field type "
  199. << field->type();
  200. }
  201. #undef STORE_TYPE
  202. #undef HANDLE_TYPE
  203. }
  204. bool ReflectiveValidator(const void* arg, int val) {
  205. auto d = static_cast<const EnumDescriptor*>(arg);
  206. return d->FindValueByNumber(val) != nullptr;
  207. }
  208. const char* ParsePackedField(const FieldDescriptor* field, Message* msg,
  209. const Reflection* reflection, const char* ptr,
  210. internal::ParseContext* ctx) {
  211. switch (field->type()) {
  212. #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME) \
  213. case FieldDescriptor::TYPE_##TYPE: \
  214. return internal::Packed##METHOD_NAME##Parser( \
  215. reflection->MutableRepeatedField<CPPTYPE>(msg, field), ptr, ctx)
  216. HANDLE_PACKED_TYPE(INT32, int32, Int32);
  217. HANDLE_PACKED_TYPE(INT64, int64, Int64);
  218. HANDLE_PACKED_TYPE(SINT32, int32, SInt32);
  219. HANDLE_PACKED_TYPE(SINT64, int64, SInt64);
  220. HANDLE_PACKED_TYPE(UINT32, uint32, UInt32);
  221. HANDLE_PACKED_TYPE(UINT64, uint64, UInt64);
  222. HANDLE_PACKED_TYPE(BOOL, bool, Bool);
  223. case FieldDescriptor::TYPE_ENUM: {
  224. auto object =
  225. internal::ReflectionAccessor::GetRepeatedEnum(reflection, field, msg);
  226. if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
  227. return internal::PackedEnumParser(object, ptr, ctx);
  228. } else {
  229. return internal::PackedEnumParserArg(
  230. object, ptr, ctx, ReflectiveValidator, field->enum_type(),
  231. internal::ReflectionAccessor::MutableInternalMetadataWithArena(
  232. reflection, msg),
  233. field->number());
  234. }
  235. }
  236. HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32);
  237. HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64);
  238. HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32);
  239. HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64);
  240. HANDLE_PACKED_TYPE(FLOAT, float, Float);
  241. HANDLE_PACKED_TYPE(DOUBLE, double, Double);
  242. #undef HANDLE_PACKED_TYPE
  243. default:
  244. GOOGLE_LOG(FATAL) << "Type is not packable " << field->type();
  245. return nullptr; // Make compiler happy
  246. }
  247. }
  248. const char* ParseLenDelim(int field_number, const FieldDescriptor* field,
  249. Message* msg, const Reflection* reflection,
  250. const char* ptr, internal::ParseContext* ctx) {
  251. if (WireFormat::WireTypeForFieldType(field->type()) !=
  252. WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
  253. GOOGLE_DCHECK(field->is_packable());
  254. return ParsePackedField(field, msg, reflection, ptr, ctx);
  255. }
  256. enum { kNone = 0, kVerify, kStrict } utf8_level = kNone;
  257. const char* field_name = nullptr;
  258. auto parse_string = [ptr, ctx, &utf8_level,
  259. &field_name](std::string* s) -> const char* {
  260. switch (utf8_level) {
  261. case kNone:
  262. return internal::InlineGreedyStringParser(s, ptr, ctx);
  263. case kVerify:
  264. return internal::InlineGreedyStringParserUTF8Verify(s, ptr, ctx,
  265. field_name);
  266. case kStrict:
  267. return internal::InlineGreedyStringParserUTF8(s, ptr, ctx, field_name);
  268. }
  269. GOOGLE_LOG(FATAL) << "Should not reach here";
  270. return nullptr; // Make compiler happy
  271. };
  272. switch (field->type()) {
  273. case FieldDescriptor::TYPE_STRING: {
  274. bool enforce_utf8 = true;
  275. bool utf8_verification = true;
  276. if (enforce_utf8 &&
  277. field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
  278. utf8_level = kStrict;
  279. } else if (utf8_verification) {
  280. utf8_level = kVerify;
  281. }
  282. field_name = field->full_name().c_str();
  283. PROTOBUF_FALLTHROUGH_INTENDED;
  284. }
  285. case FieldDescriptor::TYPE_BYTES: {
  286. if (field->is_repeated()) {
  287. int index = reflection->FieldSize(*msg, field);
  288. // Add new empty value.
  289. reflection->AddString(msg, field, "");
  290. if (field->options().ctype() == FieldOptions::STRING ||
  291. field->is_extension()) {
  292. auto object =
  293. reflection->MutableRepeatedPtrField<std::string>(msg, field)
  294. ->Mutable(index);
  295. return parse_string(object);
  296. } else {
  297. auto object =
  298. reflection->MutableRepeatedPtrField<std::string>(msg, field)
  299. ->Mutable(index);
  300. return parse_string(object);
  301. }
  302. } else {
  303. // Clear value and make sure it's set.
  304. reflection->SetString(msg, field, "");
  305. if (field->options().ctype() == FieldOptions::STRING ||
  306. field->is_extension()) {
  307. // HACK around inability to get mutable_string in reflection
  308. std::string* object = &const_cast<std::string&>(
  309. reflection->GetStringReference(*msg, field, nullptr));
  310. return parse_string(object);
  311. } else {
  312. // HACK around inability to get mutable_string in reflection
  313. std::string* object = &const_cast<std::string&>(
  314. reflection->GetStringReference(*msg, field, nullptr));
  315. return parse_string(object);
  316. }
  317. }
  318. GOOGLE_LOG(FATAL) << "No other type than string supported";
  319. }
  320. case FieldDescriptor::TYPE_MESSAGE: {
  321. Message* object;
  322. if (field->is_repeated()) {
  323. object = reflection->AddMessage(msg, field, ctx->data().factory);
  324. } else {
  325. object = reflection->MutableMessage(msg, field, ctx->data().factory);
  326. }
  327. return ctx->ParseMessage(object, ptr);
  328. }
  329. default:
  330. GOOGLE_LOG(FATAL) << "Wrong type for length delim " << field->type();
  331. }
  332. return nullptr; // Make compiler happy.
  333. }
  334. Message* GetGroup(int field_number, const FieldDescriptor* field, Message* msg,
  335. const Reflection* reflection) {
  336. if (field->is_repeated()) {
  337. return reflection->AddMessage(msg, field, nullptr);
  338. } else {
  339. return reflection->MutableMessage(msg, field, nullptr);
  340. }
  341. }
  342. const char* Message::_InternalParse(const char* ptr,
  343. internal::ParseContext* ctx) {
  344. class ReflectiveFieldParser {
  345. public:
  346. ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx)
  347. : ReflectiveFieldParser(msg, ctx, false) {}
  348. void AddVarint(uint32 num, uint64 value) {
  349. if (is_item_ && num == 2) {
  350. if (!payload_.empty()) {
  351. auto field = Field(value, 2);
  352. if (field && field->message_type()) {
  353. auto child = reflection_->MutableMessage(msg_, field);
  354. // TODO(gerbens) signal error
  355. child->ParsePartialFromString(payload_);
  356. } else {
  357. MutableUnknown()->AddLengthDelimited(value)->swap(payload_);
  358. }
  359. return;
  360. }
  361. type_id_ = value;
  362. return;
  363. }
  364. auto field = Field(num, 0);
  365. if (field) {
  366. SetField(value, field, msg_, reflection_);
  367. } else {
  368. MutableUnknown()->AddVarint(num, value);
  369. }
  370. }
  371. void AddFixed64(uint32 num, uint64 value) {
  372. auto field = Field(num, 1);
  373. if (field) {
  374. SetField(value, field, msg_, reflection_);
  375. } else {
  376. MutableUnknown()->AddFixed64(num, value);
  377. }
  378. }
  379. const char* ParseLengthDelimited(uint32 num, const char* ptr,
  380. internal::ParseContext* ctx) {
  381. if (is_item_ && num == 3) {
  382. if (type_id_ == 0) {
  383. return InlineGreedyStringParser(&payload_, ptr, ctx);
  384. }
  385. num = type_id_;
  386. type_id_ = 0;
  387. }
  388. auto field = Field(num, 2);
  389. if (field) {
  390. return ParseLenDelim(num, field, msg_, reflection_, ptr, ctx);
  391. } else {
  392. return InlineGreedyStringParser(
  393. MutableUnknown()->AddLengthDelimited(num), ptr, ctx);
  394. }
  395. }
  396. const char* ParseGroup(uint32 num, const char* ptr,
  397. internal::ParseContext* ctx) {
  398. if (!is_item_ && descriptor_->options().message_set_wire_format() &&
  399. num == 1) {
  400. is_item_ = true;
  401. ptr = ctx->ParseGroup(this, ptr, num * 8 + 3);
  402. is_item_ = false;
  403. type_id_ = 0;
  404. return ptr;
  405. }
  406. auto field = Field(num, 3);
  407. if (field) {
  408. auto msg = GetGroup(num, field, msg_, reflection_);
  409. return ctx->ParseGroup(msg, ptr, num * 8 + 3);
  410. } else {
  411. return UnknownFieldParse(num * 8 + 3, MutableUnknown(), ptr, ctx);
  412. }
  413. }
  414. void AddFixed32(uint32 num, uint32 value) {
  415. auto field = Field(num, 5);
  416. if (field) {
  417. SetField(value, field, msg_, reflection_);
  418. } else {
  419. MutableUnknown()->AddFixed32(num, value);
  420. }
  421. }
  422. const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
  423. // We're parsing the a MessageSetItem
  424. GOOGLE_DCHECK(is_item_);
  425. return internal::WireFormatParser(*this, ptr, ctx);
  426. }
  427. private:
  428. Message* msg_;
  429. const Descriptor* descriptor_;
  430. const Reflection* reflection_;
  431. internal::ParseContext* ctx_;
  432. UnknownFieldSet* unknown_ = nullptr;
  433. bool is_item_ = false;
  434. uint32 type_id_ = 0;
  435. std::string payload_;
  436. ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx,
  437. bool is_item)
  438. : msg_(msg),
  439. descriptor_(msg->GetDescriptor()),
  440. reflection_(msg->GetReflection()),
  441. ctx_(ctx),
  442. is_item_(is_item) {
  443. GOOGLE_CHECK(descriptor_) << msg->GetTypeName();
  444. GOOGLE_CHECK(reflection_) << msg->GetTypeName();
  445. }
  446. const FieldDescriptor* Field(int num, int wire_type) {
  447. auto field = descriptor_->FindFieldByNumber(num);
  448. // If that failed, check if the field is an extension.
  449. if (field == nullptr && descriptor_->IsExtensionNumber(num)) {
  450. const DescriptorPool* pool = ctx_->data().pool;
  451. if (pool == NULL) {
  452. field = reflection_->FindKnownExtensionByNumber(num);
  453. } else {
  454. field = pool->FindExtensionByNumber(descriptor_, num);
  455. }
  456. }
  457. if (field == nullptr) return nullptr;
  458. if (internal::WireFormat::WireTypeForFieldType(field->type()) !=
  459. wire_type) {
  460. if (field->is_packable()) {
  461. if (wire_type ==
  462. internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
  463. return field;
  464. }
  465. }
  466. return nullptr;
  467. }
  468. return field;
  469. }
  470. UnknownFieldSet* MutableUnknown() {
  471. if (unknown_) return unknown_;
  472. return unknown_ = reflection_->MutableUnknownFields(msg_);
  473. }
  474. };
  475. ReflectiveFieldParser field_parser(this, ctx);
  476. return internal::WireFormatParser(field_parser, ptr, ctx);
  477. }
  478. uint8* Message::InternalSerializeWithCachedSizesToArray(
  479. uint8* target, io::EpsCopyOutputStream* stream) const {
  480. return WireFormat::InternalSerializeWithCachedSizesToArray(*this, target,
  481. stream);
  482. }
  483. size_t Message::ByteSizeLong() const {
  484. size_t size = WireFormat::ByteSize(*this);
  485. SetCachedSize(internal::ToCachedSize(size));
  486. return size;
  487. }
  488. void Message::SetCachedSize(int /* size */) const {
  489. GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
  490. << "\" implements neither SetCachedSize() nor ByteSize(). "
  491. "Must implement one or the other.";
  492. }
  493. size_t Message::SpaceUsedLong() const {
  494. return GetReflection()->SpaceUsedLong(*this);
  495. }
  496. // =============================================================================
  497. // MessageFactory
  498. MessageFactory::~MessageFactory() {}
  499. namespace {
  500. class GeneratedMessageFactory : public MessageFactory {
  501. public:
  502. static GeneratedMessageFactory* singleton();
  503. void RegisterFile(const google::protobuf::internal::DescriptorTable* table);
  504. void RegisterType(const Descriptor* descriptor, const Message* prototype);
  505. // implements MessageFactory ---------------------------------------
  506. const Message* GetPrototype(const Descriptor* type) override;
  507. private:
  508. // Only written at static init time, so does not require locking.
  509. std::unordered_map<const char*, const google::protobuf::internal::DescriptorTable*,
  510. hash<const char*>, streq>
  511. file_map_;
  512. internal::WrappedMutex mutex_;
  513. // Initialized lazily, so requires locking.
  514. std::unordered_map<const Descriptor*, const Message*> type_map_;
  515. };
  516. GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
  517. static auto instance =
  518. internal::OnShutdownDelete(new GeneratedMessageFactory);
  519. return instance;
  520. }
  521. void GeneratedMessageFactory::RegisterFile(
  522. const google::protobuf::internal::DescriptorTable* table) {
  523. if (!InsertIfNotPresent(&file_map_, table->filename, table)) {
  524. GOOGLE_LOG(FATAL) << "File is already registered: " << table->filename;
  525. }
  526. }
  527. void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
  528. const Message* prototype) {
  529. GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
  530. << "Tried to register a non-generated type with the generated "
  531. "type registry.";
  532. // This should only be called as a result of calling a file registration
  533. // function during GetPrototype(), in which case we already have locked
  534. // the mutex.
  535. mutex_.AssertHeld();
  536. if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
  537. GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
  538. }
  539. }
  540. const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
  541. {
  542. ReaderMutexLock lock(&mutex_);
  543. const Message* result = FindPtrOrNull(type_map_, type);
  544. if (result != NULL) return result;
  545. }
  546. // If the type is not in the generated pool, then we can't possibly handle
  547. // it.
  548. if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
  549. // Apparently the file hasn't been registered yet. Let's do that now.
  550. const internal::DescriptorTable* registration_data =
  551. FindPtrOrNull(file_map_, type->file()->name().c_str());
  552. if (registration_data == NULL) {
  553. GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
  554. "registered: "
  555. << type->file()->name();
  556. return NULL;
  557. }
  558. WriterMutexLock lock(&mutex_);
  559. // Check if another thread preempted us.
  560. const Message* result = FindPtrOrNull(type_map_, type);
  561. if (result == NULL) {
  562. // Nope. OK, register everything.
  563. internal::RegisterFileLevelMetadata(registration_data);
  564. // Should be here now.
  565. result = FindPtrOrNull(type_map_, type);
  566. }
  567. if (result == NULL) {
  568. GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
  569. << "registered: " << type->full_name();
  570. }
  571. return result;
  572. }
  573. } // namespace
  574. MessageFactory* MessageFactory::generated_factory() {
  575. return GeneratedMessageFactory::singleton();
  576. }
  577. void MessageFactory::InternalRegisterGeneratedFile(
  578. const google::protobuf::internal::DescriptorTable* table) {
  579. GeneratedMessageFactory::singleton()->RegisterFile(table);
  580. }
  581. void MessageFactory::InternalRegisterGeneratedMessage(
  582. const Descriptor* descriptor, const Message* prototype) {
  583. GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
  584. }
  585. namespace {
  586. template <typename T>
  587. T* GetSingleton() {
  588. static T singleton;
  589. return &singleton;
  590. }
  591. } // namespace
  592. const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor(
  593. const FieldDescriptor* field) const {
  594. GOOGLE_CHECK(field->is_repeated());
  595. switch (field->cpp_type()) {
  596. #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \
  597. case FieldDescriptor::CPPTYPE_##TYPE: \
  598. return GetSingleton<internal::RepeatedFieldPrimitiveAccessor<type> >();
  599. HANDLE_PRIMITIVE_TYPE(INT32, int32)
  600. HANDLE_PRIMITIVE_TYPE(UINT32, uint32)
  601. HANDLE_PRIMITIVE_TYPE(INT64, int64)
  602. HANDLE_PRIMITIVE_TYPE(UINT64, uint64)
  603. HANDLE_PRIMITIVE_TYPE(FLOAT, float)
  604. HANDLE_PRIMITIVE_TYPE(DOUBLE, double)
  605. HANDLE_PRIMITIVE_TYPE(BOOL, bool)
  606. HANDLE_PRIMITIVE_TYPE(ENUM, int32)
  607. #undef HANDLE_PRIMITIVE_TYPE
  608. case FieldDescriptor::CPPTYPE_STRING:
  609. switch (field->options().ctype()) {
  610. default:
  611. case FieldOptions::STRING:
  612. return GetSingleton<internal::RepeatedPtrFieldStringAccessor>();
  613. }
  614. break;
  615. case FieldDescriptor::CPPTYPE_MESSAGE:
  616. if (field->is_map()) {
  617. return GetSingleton<internal::MapFieldAccessor>();
  618. } else {
  619. return GetSingleton<internal::RepeatedPtrFieldMessageAccessor>();
  620. }
  621. }
  622. GOOGLE_LOG(FATAL) << "Should not reach here.";
  623. return NULL;
  624. }
  625. namespace internal {
  626. template <>
  627. #if defined(_MSC_VER) && (_MSC_VER >= 1800)
  628. // Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
  629. // #240
  630. PROTOBUF_NOINLINE
  631. #endif
  632. Message*
  633. GenericTypeHandler<Message>::NewFromPrototype(const Message* prototype,
  634. Arena* arena) {
  635. return prototype->New(arena);
  636. }
  637. template <>
  638. #if defined(_MSC_VER) && (_MSC_VER >= 1800)
  639. // Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
  640. // #240
  641. PROTOBUF_NOINLINE
  642. #endif
  643. Arena*
  644. GenericTypeHandler<Message>::GetArena(Message* value) {
  645. return value->GetArena();
  646. }
  647. template <>
  648. #if defined(_MSC_VER) && (_MSC_VER >= 1800)
  649. // Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
  650. // #240
  651. PROTOBUF_NOINLINE
  652. #endif
  653. void*
  654. GenericTypeHandler<Message>::GetMaybeArenaPointer(Message* value) {
  655. return value->GetMaybeArenaPointer();
  656. }
  657. } // namespace internal
  658. } // namespace protobuf
  659. } // namespace google