诸暨麻将添加redis
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

537 rader
20 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. //
  34. // Contains methods defined in extension_set.h which cannot be part of the
  35. // lite library because they use descriptors or reflection.
  36. #include <google/protobuf/extension_set.h>
  37. #include <google/protobuf/stubs/casts.h>
  38. #include <google/protobuf/descriptor.pb.h>
  39. #include <google/protobuf/extension_set_inl.h>
  40. #include <google/protobuf/parse_context.h>
  41. #include <google/protobuf/io/coded_stream.h>
  42. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  43. #include <google/protobuf/descriptor.h>
  44. #include <google/protobuf/message.h>
  45. #include <google/protobuf/repeated_field.h>
  46. #include <google/protobuf/unknown_field_set.h>
  47. #include <google/protobuf/wire_format.h>
  48. #include <google/protobuf/wire_format_lite.h>
  49. #include <google/protobuf/port_def.inc>
  50. namespace google {
  51. namespace protobuf {
  52. namespace internal {
  53. // A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
  54. class MessageSetFieldSkipper : public UnknownFieldSetFieldSkipper {
  55. public:
  56. explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
  57. : UnknownFieldSetFieldSkipper(unknown_fields) {}
  58. virtual ~MessageSetFieldSkipper() {}
  59. virtual bool SkipMessageSetField(io::CodedInputStream* input,
  60. int field_number);
  61. };
  62. bool MessageSetFieldSkipper::SkipMessageSetField(io::CodedInputStream* input,
  63. int field_number) {
  64. uint32 length;
  65. if (!input->ReadVarint32(&length)) return false;
  66. if (unknown_fields_ == NULL) {
  67. return input->Skip(length);
  68. } else {
  69. return input->ReadString(unknown_fields_->AddLengthDelimited(field_number),
  70. length);
  71. }
  72. }
  73. // Implementation of ExtensionFinder which finds extensions in a given
  74. // DescriptorPool, using the given MessageFactory to construct sub-objects.
  75. // This class is implemented in extension_set_heavy.cc.
  76. class DescriptorPoolExtensionFinder : public ExtensionFinder {
  77. public:
  78. DescriptorPoolExtensionFinder(const DescriptorPool* pool,
  79. MessageFactory* factory,
  80. const Descriptor* containing_type)
  81. : pool_(pool), factory_(factory), containing_type_(containing_type) {}
  82. ~DescriptorPoolExtensionFinder() override {}
  83. bool Find(int number, ExtensionInfo* output) override;
  84. private:
  85. const DescriptorPool* pool_;
  86. MessageFactory* factory_;
  87. const Descriptor* containing_type_;
  88. };
  89. void ExtensionSet::AppendToList(
  90. const Descriptor* containing_type, const DescriptorPool* pool,
  91. std::vector<const FieldDescriptor*>* output) const {
  92. ForEach([containing_type, pool, &output](int number, const Extension& ext) {
  93. bool has = false;
  94. if (ext.is_repeated) {
  95. has = ext.GetSize() > 0;
  96. } else {
  97. has = !ext.is_cleared;
  98. }
  99. if (has) {
  100. // TODO(kenton): Looking up each field by number is somewhat unfortunate.
  101. // Is there a better way? The problem is that descriptors are lazily-
  102. // initialized, so they might not even be constructed until
  103. // AppendToList() is called.
  104. if (ext.descriptor == NULL) {
  105. output->push_back(pool->FindExtensionByNumber(containing_type, number));
  106. } else {
  107. output->push_back(ext.descriptor);
  108. }
  109. }
  110. });
  111. }
  112. inline FieldDescriptor::Type real_type(FieldType type) {
  113. GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
  114. return static_cast<FieldDescriptor::Type>(type);
  115. }
  116. inline FieldDescriptor::CppType cpp_type(FieldType type) {
  117. return FieldDescriptor::TypeToCppType(
  118. static_cast<FieldDescriptor::Type>(type));
  119. }
  120. inline WireFormatLite::FieldType field_type(FieldType type) {
  121. GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
  122. return static_cast<WireFormatLite::FieldType>(type);
  123. }
  124. #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
  125. GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
  126. : FieldDescriptor::LABEL_OPTIONAL, \
  127. FieldDescriptor::LABEL_##LABEL); \
  128. GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
  129. const MessageLite& ExtensionSet::GetMessage(int number,
  130. const Descriptor* message_type,
  131. MessageFactory* factory) const {
  132. const Extension* extension = FindOrNull(number);
  133. if (extension == NULL || extension->is_cleared) {
  134. // Not present. Return the default value.
  135. return *factory->GetPrototype(message_type);
  136. } else {
  137. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  138. if (extension->is_lazy) {
  139. return extension->lazymessage_value->GetMessage(
  140. *factory->GetPrototype(message_type));
  141. } else {
  142. return *extension->message_value;
  143. }
  144. }
  145. }
  146. MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
  147. MessageFactory* factory) {
  148. Extension* extension;
  149. if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
  150. extension->type = descriptor->type();
  151. GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
  152. extension->is_repeated = false;
  153. extension->is_packed = false;
  154. const MessageLite* prototype =
  155. factory->GetPrototype(descriptor->message_type());
  156. extension->is_lazy = false;
  157. extension->message_value = prototype->New(arena_);
  158. extension->is_cleared = false;
  159. return extension->message_value;
  160. } else {
  161. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  162. extension->is_cleared = false;
  163. if (extension->is_lazy) {
  164. return extension->lazymessage_value->MutableMessage(
  165. *factory->GetPrototype(descriptor->message_type()));
  166. } else {
  167. return extension->message_value;
  168. }
  169. }
  170. }
  171. MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
  172. MessageFactory* factory) {
  173. Extension* extension = FindOrNull(descriptor->number());
  174. if (extension == NULL) {
  175. // Not present. Return NULL.
  176. return NULL;
  177. } else {
  178. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  179. MessageLite* ret = NULL;
  180. if (extension->is_lazy) {
  181. ret = extension->lazymessage_value->ReleaseMessage(
  182. *factory->GetPrototype(descriptor->message_type()));
  183. if (arena_ == NULL) {
  184. delete extension->lazymessage_value;
  185. }
  186. } else {
  187. if (arena_ != NULL) {
  188. ret = extension->message_value->New();
  189. ret->CheckTypeAndMergeFrom(*extension->message_value);
  190. } else {
  191. ret = extension->message_value;
  192. }
  193. }
  194. Erase(descriptor->number());
  195. return ret;
  196. }
  197. }
  198. MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
  199. const FieldDescriptor* descriptor, MessageFactory* factory) {
  200. Extension* extension = FindOrNull(descriptor->number());
  201. if (extension == NULL) {
  202. // Not present. Return NULL.
  203. return NULL;
  204. } else {
  205. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  206. MessageLite* ret = NULL;
  207. if (extension->is_lazy) {
  208. ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(
  209. *factory->GetPrototype(descriptor->message_type()));
  210. if (arena_ == NULL) {
  211. delete extension->lazymessage_value;
  212. }
  213. } else {
  214. ret = extension->message_value;
  215. }
  216. Erase(descriptor->number());
  217. return ret;
  218. }
  219. }
  220. ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(
  221. const FieldDescriptor* descriptor) {
  222. Extension* extension;
  223. if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
  224. extension->type = descriptor->type();
  225. GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
  226. extension->is_repeated = true;
  227. extension->repeated_message_value =
  228. Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
  229. } else {
  230. GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
  231. }
  232. return extension;
  233. }
  234. MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
  235. MessageFactory* factory) {
  236. Extension* extension = MaybeNewRepeatedExtension(descriptor);
  237. // RepeatedPtrField<Message> does not know how to Add() since it cannot
  238. // allocate an abstract object, so we have to be tricky.
  239. MessageLite* result =
  240. reinterpret_cast<internal::RepeatedPtrFieldBase*>(
  241. extension->repeated_message_value)
  242. ->AddFromCleared<GenericTypeHandler<MessageLite> >();
  243. if (result == NULL) {
  244. const MessageLite* prototype;
  245. if (extension->repeated_message_value->size() == 0) {
  246. prototype = factory->GetPrototype(descriptor->message_type());
  247. GOOGLE_CHECK(prototype != NULL);
  248. } else {
  249. prototype = &extension->repeated_message_value->Get(0);
  250. }
  251. result = prototype->New(arena_);
  252. extension->repeated_message_value->AddAllocated(result);
  253. }
  254. return result;
  255. }
  256. void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
  257. MessageLite* new_entry) {
  258. Extension* extension = MaybeNewRepeatedExtension(descriptor);
  259. extension->repeated_message_value->AddAllocated(new_entry);
  260. }
  261. static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
  262. return reinterpret_cast<const EnumDescriptor*>(arg)->FindValueByNumber(
  263. number) != NULL;
  264. }
  265. bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
  266. const FieldDescriptor* extension =
  267. pool_->FindExtensionByNumber(containing_type_, number);
  268. if (extension == NULL) {
  269. return false;
  270. } else {
  271. output->type = extension->type();
  272. output->is_repeated = extension->is_repeated();
  273. output->is_packed = extension->options().packed();
  274. output->descriptor = extension;
  275. if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  276. output->message_info.prototype =
  277. factory_->GetPrototype(extension->message_type());
  278. GOOGLE_CHECK(output->message_info.prototype != nullptr)
  279. << "Extension factory's GetPrototype() returned NULL for extension: "
  280. << extension->full_name();
  281. } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
  282. output->enum_validity_check.func = ValidateEnumUsingDescriptor;
  283. output->enum_validity_check.arg = extension->enum_type();
  284. }
  285. return true;
  286. }
  287. }
  288. bool ExtensionSet::FindExtension(int wire_type, uint32 field,
  289. const Message* containing_type,
  290. const internal::ParseContext* ctx,
  291. ExtensionInfo* extension,
  292. bool* was_packed_on_wire) {
  293. if (ctx->data().pool == nullptr) {
  294. GeneratedExtensionFinder finder(containing_type);
  295. if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
  296. was_packed_on_wire)) {
  297. return false;
  298. }
  299. } else {
  300. DescriptorPoolExtensionFinder finder(ctx->data().pool, ctx->data().factory,
  301. containing_type->GetDescriptor());
  302. if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
  303. was_packed_on_wire)) {
  304. return false;
  305. }
  306. }
  307. return true;
  308. }
  309. const char* ExtensionSet::ParseField(
  310. uint64 tag, const char* ptr, const Message* containing_type,
  311. internal::InternalMetadataWithArena* metadata,
  312. internal::ParseContext* ctx) {
  313. int number = tag >> 3;
  314. bool was_packed_on_wire;
  315. ExtensionInfo extension;
  316. if (!FindExtension(tag & 7, number, containing_type, ctx, &extension,
  317. &was_packed_on_wire)) {
  318. return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx);
  319. }
  320. return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
  321. metadata, ptr, ctx);
  322. }
  323. const char* ExtensionSet::ParseFieldMaybeLazily(
  324. uint64 tag, const char* ptr, const Message* containing_type,
  325. internal::InternalMetadataWithArena* metadata,
  326. internal::ParseContext* ctx) {
  327. return ParseField(tag, ptr, containing_type, metadata, ctx);
  328. }
  329. const char* ExtensionSet::ParseMessageSetItem(
  330. const char* ptr, const Message* containing_type,
  331. internal::InternalMetadataWithArena* metadata,
  332. internal::ParseContext* ctx) {
  333. return ParseMessageSetItemTmpl(ptr, containing_type, metadata, ctx);
  334. }
  335. bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
  336. const Message* containing_type,
  337. UnknownFieldSet* unknown_fields) {
  338. UnknownFieldSetFieldSkipper skipper(unknown_fields);
  339. if (input->GetExtensionPool() == NULL) {
  340. GeneratedExtensionFinder finder(containing_type);
  341. return ParseField(tag, input, &finder, &skipper);
  342. } else {
  343. DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
  344. input->GetExtensionFactory(),
  345. containing_type->GetDescriptor());
  346. return ParseField(tag, input, &finder, &skipper);
  347. }
  348. }
  349. bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
  350. const Message* containing_type,
  351. UnknownFieldSet* unknown_fields) {
  352. MessageSetFieldSkipper skipper(unknown_fields);
  353. if (input->GetExtensionPool() == NULL) {
  354. GeneratedExtensionFinder finder(containing_type);
  355. return ParseMessageSet(input, &finder, &skipper);
  356. } else {
  357. DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
  358. input->GetExtensionFactory(),
  359. containing_type->GetDescriptor());
  360. return ParseMessageSet(input, &finder, &skipper);
  361. }
  362. }
  363. int ExtensionSet::SpaceUsedExcludingSelf() const {
  364. return internal::FromIntSize(SpaceUsedExcludingSelfLong());
  365. }
  366. size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
  367. size_t total_size = Size() * sizeof(KeyValue);
  368. ForEach([&total_size](int /* number */, const Extension& ext) {
  369. total_size += ext.SpaceUsedExcludingSelfLong();
  370. });
  371. return total_size;
  372. }
  373. inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong(
  374. RepeatedPtrFieldBase* field) {
  375. return field->SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
  376. }
  377. size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
  378. size_t total_size = 0;
  379. if (is_repeated) {
  380. switch (cpp_type(type)) {
  381. #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
  382. case FieldDescriptor::CPPTYPE_##UPPERCASE: \
  383. total_size += sizeof(*repeated_##LOWERCASE##_value) + \
  384. repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \
  385. break
  386. HANDLE_TYPE(INT32, int32);
  387. HANDLE_TYPE(INT64, int64);
  388. HANDLE_TYPE(UINT32, uint32);
  389. HANDLE_TYPE(UINT64, uint64);
  390. HANDLE_TYPE(FLOAT, float);
  391. HANDLE_TYPE(DOUBLE, double);
  392. HANDLE_TYPE(BOOL, bool);
  393. HANDLE_TYPE(ENUM, enum);
  394. HANDLE_TYPE(STRING, string);
  395. #undef HANDLE_TYPE
  396. case FieldDescriptor::CPPTYPE_MESSAGE:
  397. // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
  398. // but MessageLite has no SpaceUsedLong(), so we must directly call
  399. // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different
  400. // type handler.
  401. total_size += sizeof(*repeated_message_value) +
  402. RepeatedMessage_SpaceUsedExcludingSelfLong(
  403. reinterpret_cast<internal::RepeatedPtrFieldBase*>(
  404. repeated_message_value));
  405. break;
  406. }
  407. } else {
  408. switch (cpp_type(type)) {
  409. case FieldDescriptor::CPPTYPE_STRING:
  410. total_size += sizeof(*string_value) +
  411. StringSpaceUsedExcludingSelfLong(*string_value);
  412. break;
  413. case FieldDescriptor::CPPTYPE_MESSAGE:
  414. if (is_lazy) {
  415. total_size += lazymessage_value->SpaceUsedLong();
  416. } else {
  417. total_size += down_cast<Message*>(message_value)->SpaceUsedLong();
  418. }
  419. break;
  420. default:
  421. // No extra storage costs for primitive types.
  422. break;
  423. }
  424. }
  425. return total_size;
  426. }
  427. uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
  428. uint8* target) const {
  429. io::EpsCopyOutputStream stream(
  430. target, MessageSetByteSize(),
  431. io::CodedOutputStream::IsDefaultSerializationDeterministic());
  432. return InternalSerializeMessageSetWithCachedSizesToArray(target, &stream);
  433. }
  434. bool ExtensionSet::ParseFieldMaybeLazily(
  435. int wire_type, int field_number, io::CodedInputStream* input,
  436. ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper) {
  437. return ParseField(
  438. WireFormatLite::MakeTag(field_number,
  439. static_cast<WireFormatLite::WireType>(wire_type)),
  440. input, extension_finder, field_skipper);
  441. }
  442. bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
  443. ExtensionFinder* extension_finder,
  444. MessageSetFieldSkipper* field_skipper) {
  445. while (true) {
  446. const uint32 tag = input->ReadTag();
  447. switch (tag) {
  448. case 0:
  449. return true;
  450. case WireFormatLite::kMessageSetItemStartTag:
  451. if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
  452. return false;
  453. }
  454. break;
  455. default:
  456. if (!ParseField(tag, input, extension_finder, field_skipper)) {
  457. return false;
  458. }
  459. break;
  460. }
  461. }
  462. }
  463. bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
  464. ExtensionFinder* extension_finder,
  465. MessageSetFieldSkipper* field_skipper) {
  466. struct MSFull {
  467. bool ParseField(int type_id, io::CodedInputStream* input) {
  468. return me->ParseFieldMaybeLazily(
  469. WireFormatLite::WIRETYPE_LENGTH_DELIMITED, type_id, input,
  470. extension_finder, field_skipper);
  471. }
  472. bool SkipField(uint32 tag, io::CodedInputStream* input) {
  473. return field_skipper->SkipField(input, tag);
  474. }
  475. ExtensionSet* me;
  476. ExtensionFinder* extension_finder;
  477. MessageSetFieldSkipper* field_skipper;
  478. };
  479. return ParseMessageSetItemImpl(input,
  480. MSFull{this, extension_finder, field_skipper});
  481. }
  482. } // namespace internal
  483. } // namespace protobuf
  484. } // namespace google