extension_set_heavy.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  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/stubs/casts.h>
  37. #include <google/protobuf/descriptor.pb.h>
  38. #include <google/protobuf/io/coded_stream.h>
  39. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  40. #include <google/protobuf/descriptor.h>
  41. #include <google/protobuf/extension_set.h>
  42. #include <google/protobuf/message.h>
  43. #include <google/protobuf/repeated_field.h>
  44. #include <google/protobuf/unknown_field_set.h>
  45. #include <google/protobuf/wire_format.h>
  46. #include <google/protobuf/wire_format_lite_inl.h>
  47. namespace google {
  48. namespace protobuf {
  49. namespace internal {
  50. // A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
  51. class MessageSetFieldSkipper
  52. : public UnknownFieldSetFieldSkipper {
  53. public:
  54. explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
  55. : UnknownFieldSetFieldSkipper(unknown_fields) {}
  56. virtual ~MessageSetFieldSkipper() {}
  57. virtual bool SkipMessageSetField(io::CodedInputStream* input,
  58. int field_number);
  59. };
  60. bool MessageSetFieldSkipper::SkipMessageSetField(
  61. io::CodedInputStream* input, int field_number) {
  62. uint32 length;
  63. if (!input->ReadVarint32(&length)) return false;
  64. if (unknown_fields_ == NULL) {
  65. return input->Skip(length);
  66. } else {
  67. return input->ReadString(
  68. unknown_fields_->AddLengthDelimited(field_number), length);
  69. }
  70. }
  71. // Implementation of ExtensionFinder which finds extensions in a given
  72. // DescriptorPool, using the given MessageFactory to construct sub-objects.
  73. // This class is implemented in extension_set_heavy.cc.
  74. class DescriptorPoolExtensionFinder : public ExtensionFinder {
  75. public:
  76. DescriptorPoolExtensionFinder(const DescriptorPool* pool,
  77. MessageFactory* factory,
  78. const Descriptor* containing_type)
  79. : pool_(pool), factory_(factory), containing_type_(containing_type) {}
  80. virtual ~DescriptorPoolExtensionFinder() {}
  81. virtual bool Find(int number, ExtensionInfo* output);
  82. private:
  83. const DescriptorPool* pool_;
  84. MessageFactory* factory_;
  85. const Descriptor* containing_type_;
  86. };
  87. void ExtensionSet::AppendToList(
  88. const Descriptor* containing_type, const DescriptorPool* pool,
  89. std::vector<const FieldDescriptor*>* output) const {
  90. ForEach([containing_type, pool, &output](int number, const Extension& ext) {
  91. bool has = false;
  92. if (ext.is_repeated) {
  93. has = ext.GetSize() > 0;
  94. } else {
  95. has = !ext.is_cleared;
  96. }
  97. if (has) {
  98. // TODO(kenton): Looking up each field by number is somewhat unfortunate.
  99. // Is there a better way? The problem is that descriptors are lazily-
  100. // initialized, so they might not even be constructed until
  101. // AppendToList() is called.
  102. if (ext.descriptor == NULL) {
  103. output->push_back(pool->FindExtensionByNumber(containing_type, number));
  104. } else {
  105. output->push_back(ext.descriptor);
  106. }
  107. }
  108. });
  109. }
  110. inline FieldDescriptor::Type real_type(FieldType type) {
  111. GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
  112. return static_cast<FieldDescriptor::Type>(type);
  113. }
  114. inline FieldDescriptor::CppType cpp_type(FieldType type) {
  115. return FieldDescriptor::TypeToCppType(
  116. static_cast<FieldDescriptor::Type>(type));
  117. }
  118. inline WireFormatLite::FieldType field_type(FieldType type) {
  119. GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
  120. return static_cast<WireFormatLite::FieldType>(type);
  121. }
  122. #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
  123. GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
  124. : FieldDescriptor::LABEL_OPTIONAL, \
  125. FieldDescriptor::LABEL_##LABEL); \
  126. GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
  127. const MessageLite& ExtensionSet::GetMessage(int number,
  128. const Descriptor* message_type,
  129. MessageFactory* factory) const {
  130. const Extension* extension = FindOrNull(number);
  131. if (extension == NULL || extension->is_cleared) {
  132. // Not present. Return the default value.
  133. return *factory->GetPrototype(message_type);
  134. } else {
  135. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  136. if (extension->is_lazy) {
  137. return extension->lazymessage_value->GetMessage(
  138. *factory->GetPrototype(message_type));
  139. } else {
  140. return *extension->message_value;
  141. }
  142. }
  143. }
  144. MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
  145. MessageFactory* factory) {
  146. Extension* extension;
  147. if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
  148. extension->type = descriptor->type();
  149. GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
  150. extension->is_repeated = false;
  151. extension->is_packed = false;
  152. const MessageLite* prototype =
  153. factory->GetPrototype(descriptor->message_type());
  154. extension->is_lazy = false;
  155. extension->message_value = prototype->New(arena_);
  156. extension->is_cleared = false;
  157. return extension->message_value;
  158. } else {
  159. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  160. extension->is_cleared = false;
  161. if (extension->is_lazy) {
  162. return extension->lazymessage_value->MutableMessage(
  163. *factory->GetPrototype(descriptor->message_type()));
  164. } else {
  165. return extension->message_value;
  166. }
  167. }
  168. }
  169. MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
  170. MessageFactory* factory) {
  171. Extension* extension = FindOrNull(descriptor->number());
  172. if (extension == NULL) {
  173. // Not present. Return NULL.
  174. return NULL;
  175. } else {
  176. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  177. MessageLite* ret = NULL;
  178. if (extension->is_lazy) {
  179. ret = extension->lazymessage_value->ReleaseMessage(
  180. *factory->GetPrototype(descriptor->message_type()));
  181. if (arena_ == NULL) {
  182. delete extension->lazymessage_value;
  183. }
  184. } else {
  185. if (arena_ != NULL) {
  186. ret = extension->message_value->New();
  187. ret->CheckTypeAndMergeFrom(*extension->message_value);
  188. } else {
  189. ret = extension->message_value;
  190. }
  191. }
  192. Erase(descriptor->number());
  193. return ret;
  194. }
  195. }
  196. MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
  197. const FieldDescriptor* descriptor, MessageFactory* factory) {
  198. Extension* extension = FindOrNull(descriptor->number());
  199. if (extension == NULL) {
  200. // Not present. Return NULL.
  201. return NULL;
  202. } else {
  203. GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
  204. MessageLite* ret = NULL;
  205. if (extension->is_lazy) {
  206. ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(
  207. *factory->GetPrototype(descriptor->message_type()));
  208. if (arena_ == NULL) {
  209. delete extension->lazymessage_value;
  210. }
  211. } else {
  212. ret = extension->message_value;
  213. }
  214. Erase(descriptor->number());
  215. return ret;
  216. }
  217. }
  218. ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) {
  219. Extension* extension;
  220. if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
  221. extension->type = descriptor->type();
  222. GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
  223. extension->is_repeated = true;
  224. extension->repeated_message_value =
  225. ::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
  226. } else {
  227. GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
  228. }
  229. return extension;
  230. }
  231. MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
  232. MessageFactory* factory) {
  233. Extension* extension = MaybeNewRepeatedExtension(descriptor);
  234. // RepeatedPtrField<Message> does not know how to Add() since it cannot
  235. // allocate an abstract object, so we have to be tricky.
  236. MessageLite* result =
  237. reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
  238. extension->repeated_message_value)
  239. ->AddFromCleared<GenericTypeHandler<MessageLite> >();
  240. if (result == NULL) {
  241. const MessageLite* prototype;
  242. if (extension->repeated_message_value->size() == 0) {
  243. prototype = factory->GetPrototype(descriptor->message_type());
  244. GOOGLE_CHECK(prototype != NULL);
  245. } else {
  246. prototype = &extension->repeated_message_value->Get(0);
  247. }
  248. result = prototype->New(arena_);
  249. extension->repeated_message_value->AddAllocated(result);
  250. }
  251. return result;
  252. }
  253. void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
  254. MessageLite* new_entry) {
  255. Extension* extension = MaybeNewRepeatedExtension(descriptor);
  256. extension->repeated_message_value->AddAllocated(new_entry);
  257. }
  258. static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
  259. return reinterpret_cast<const EnumDescriptor*>(arg)
  260. ->FindValueByNumber(number) != NULL;
  261. }
  262. bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
  263. const FieldDescriptor* extension =
  264. pool_->FindExtensionByNumber(containing_type_, number);
  265. if (extension == NULL) {
  266. return false;
  267. } else {
  268. output->type = extension->type();
  269. output->is_repeated = extension->is_repeated();
  270. output->is_packed = extension->options().packed();
  271. output->descriptor = extension;
  272. if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  273. output->message_prototype =
  274. factory_->GetPrototype(extension->message_type());
  275. GOOGLE_CHECK(output->message_prototype != NULL)
  276. << "Extension factory's GetPrototype() returned NULL for extension: "
  277. << extension->full_name();
  278. } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
  279. output->enum_validity_check.func = ValidateEnumUsingDescriptor;
  280. output->enum_validity_check.arg = extension->enum_type();
  281. }
  282. return true;
  283. }
  284. }
  285. bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
  286. const Message* containing_type,
  287. UnknownFieldSet* unknown_fields) {
  288. UnknownFieldSetFieldSkipper skipper(unknown_fields);
  289. if (input->GetExtensionPool() == NULL) {
  290. GeneratedExtensionFinder finder(containing_type);
  291. return ParseField(tag, input, &finder, &skipper);
  292. } else {
  293. DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
  294. input->GetExtensionFactory(),
  295. containing_type->GetDescriptor());
  296. return ParseField(tag, input, &finder, &skipper);
  297. }
  298. }
  299. bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
  300. const Message* containing_type,
  301. UnknownFieldSet* unknown_fields) {
  302. MessageSetFieldSkipper skipper(unknown_fields);
  303. if (input->GetExtensionPool() == NULL) {
  304. GeneratedExtensionFinder finder(containing_type);
  305. return ParseMessageSet(input, &finder, &skipper);
  306. } else {
  307. DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
  308. input->GetExtensionFactory(),
  309. containing_type->GetDescriptor());
  310. return ParseMessageSet(input, &finder, &skipper);
  311. }
  312. }
  313. int ExtensionSet::SpaceUsedExcludingSelf() const {
  314. return internal::FromIntSize(SpaceUsedExcludingSelfLong());
  315. }
  316. size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
  317. size_t total_size = Size() * sizeof(KeyValue);
  318. ForEach([&total_size](int /* number */, const Extension& ext) {
  319. total_size += ext.SpaceUsedExcludingSelfLong();
  320. });
  321. return total_size;
  322. }
  323. inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong(
  324. RepeatedPtrFieldBase* field) {
  325. return field->SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
  326. }
  327. size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
  328. size_t total_size = 0;
  329. if (is_repeated) {
  330. switch (cpp_type(type)) {
  331. #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
  332. case FieldDescriptor::CPPTYPE_##UPPERCASE: \
  333. total_size += sizeof(*repeated_##LOWERCASE##_value) + \
  334. repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \
  335. break
  336. HANDLE_TYPE( INT32, int32);
  337. HANDLE_TYPE( INT64, int64);
  338. HANDLE_TYPE( UINT32, uint32);
  339. HANDLE_TYPE( UINT64, uint64);
  340. HANDLE_TYPE( FLOAT, float);
  341. HANDLE_TYPE( DOUBLE, double);
  342. HANDLE_TYPE( BOOL, bool);
  343. HANDLE_TYPE( ENUM, enum);
  344. HANDLE_TYPE( STRING, string);
  345. #undef HANDLE_TYPE
  346. case FieldDescriptor::CPPTYPE_MESSAGE:
  347. // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
  348. // but MessageLite has no SpaceUsedLong(), so we must directly call
  349. // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different
  350. // type handler.
  351. total_size +=
  352. sizeof(*repeated_message_value) +
  353. RepeatedMessage_SpaceUsedExcludingSelfLong(
  354. reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
  355. repeated_message_value));
  356. break;
  357. }
  358. } else {
  359. switch (cpp_type(type)) {
  360. case FieldDescriptor::CPPTYPE_STRING:
  361. total_size += sizeof(*string_value) +
  362. StringSpaceUsedExcludingSelfLong(*string_value);
  363. break;
  364. case FieldDescriptor::CPPTYPE_MESSAGE:
  365. if (is_lazy) {
  366. total_size += lazymessage_value->SpaceUsedLong();
  367. } else {
  368. total_size += down_cast<Message*>(message_value)->SpaceUsedLong();
  369. }
  370. break;
  371. default:
  372. // No extra storage costs for primitive types.
  373. break;
  374. }
  375. }
  376. return total_size;
  377. }
  378. // The Serialize*ToArray methods are only needed in the heavy library, as
  379. // the lite library only generates SerializeWithCachedSizes.
  380. uint8* ExtensionSet::SerializeWithCachedSizesToArray(int start_field_number,
  381. int end_field_number,
  382. uint8* target) const {
  383. return InternalSerializeWithCachedSizesToArray(
  384. start_field_number, end_field_number,
  385. google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
  386. target);
  387. }
  388. uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
  389. uint8* target) const {
  390. return InternalSerializeMessageSetWithCachedSizesToArray(
  391. google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
  392. target);
  393. }
  394. uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
  395. int start_field_number, int end_field_number, bool deterministic,
  396. uint8* target) const {
  397. if (GOOGLE_PREDICT_FALSE(is_large())) {
  398. const auto& end = map_.large->end();
  399. for (auto it = map_.large->lower_bound(start_field_number);
  400. it != end && it->first < end_field_number; ++it) {
  401. target = it->second.InternalSerializeFieldWithCachedSizesToArray(
  402. it->first, deterministic, target);
  403. }
  404. return target;
  405. }
  406. const KeyValue* end = flat_end();
  407. for (const KeyValue* it = std::lower_bound(
  408. flat_begin(), end, start_field_number, KeyValue::FirstComparator());
  409. it != end && it->first < end_field_number; ++it) {
  410. target = it->second.InternalSerializeFieldWithCachedSizesToArray(
  411. it->first, deterministic, target);
  412. }
  413. return target;
  414. }
  415. uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
  416. bool deterministic, uint8* target) const {
  417. ForEach([deterministic, &target](int number, const Extension& ext) {
  418. target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray(
  419. number, deterministic, target);
  420. });
  421. return target;
  422. }
  423. uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
  424. int number, bool deterministic, uint8* target) const {
  425. if (is_repeated) {
  426. if (is_packed) {
  427. if (cached_size == 0) return target;
  428. target = WireFormatLite::WriteTagToArray(number,
  429. WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
  430. target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
  431. switch (real_type(type)) {
  432. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
  433. case FieldDescriptor::TYPE_##UPPERCASE: \
  434. for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
  435. target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \
  436. repeated_##LOWERCASE##_value->Get(i), target); \
  437. } \
  438. break
  439. HANDLE_TYPE( INT32, Int32, int32);
  440. HANDLE_TYPE( INT64, Int64, int64);
  441. HANDLE_TYPE( UINT32, UInt32, uint32);
  442. HANDLE_TYPE( UINT64, UInt64, uint64);
  443. HANDLE_TYPE( SINT32, SInt32, int32);
  444. HANDLE_TYPE( SINT64, SInt64, int64);
  445. HANDLE_TYPE( FIXED32, Fixed32, uint32);
  446. HANDLE_TYPE( FIXED64, Fixed64, uint64);
  447. HANDLE_TYPE(SFIXED32, SFixed32, int32);
  448. HANDLE_TYPE(SFIXED64, SFixed64, int64);
  449. HANDLE_TYPE( FLOAT, Float, float);
  450. HANDLE_TYPE( DOUBLE, Double, double);
  451. HANDLE_TYPE( BOOL, Bool, bool);
  452. HANDLE_TYPE( ENUM, Enum, enum);
  453. #undef HANDLE_TYPE
  454. case FieldDescriptor::TYPE_STRING:
  455. case FieldDescriptor::TYPE_BYTES:
  456. case FieldDescriptor::TYPE_GROUP:
  457. case FieldDescriptor::TYPE_MESSAGE:
  458. GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
  459. break;
  460. }
  461. } else {
  462. switch (real_type(type)) {
  463. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
  464. case FieldDescriptor::TYPE_##UPPERCASE: \
  465. for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
  466. target = WireFormatLite::Write##CAMELCASE##ToArray(number, \
  467. repeated_##LOWERCASE##_value->Get(i), target); \
  468. } \
  469. break
  470. HANDLE_TYPE( INT32, Int32, int32);
  471. HANDLE_TYPE( INT64, Int64, int64);
  472. HANDLE_TYPE( UINT32, UInt32, uint32);
  473. HANDLE_TYPE( UINT64, UInt64, uint64);
  474. HANDLE_TYPE( SINT32, SInt32, int32);
  475. HANDLE_TYPE( SINT64, SInt64, int64);
  476. HANDLE_TYPE( FIXED32, Fixed32, uint32);
  477. HANDLE_TYPE( FIXED64, Fixed64, uint64);
  478. HANDLE_TYPE(SFIXED32, SFixed32, int32);
  479. HANDLE_TYPE(SFIXED64, SFixed64, int64);
  480. HANDLE_TYPE( FLOAT, Float, float);
  481. HANDLE_TYPE( DOUBLE, Double, double);
  482. HANDLE_TYPE( BOOL, Bool, bool);
  483. HANDLE_TYPE( STRING, String, string);
  484. HANDLE_TYPE( BYTES, Bytes, string);
  485. HANDLE_TYPE( ENUM, Enum, enum);
  486. #undef HANDLE_TYPE
  487. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
  488. case FieldDescriptor::TYPE_##UPPERCASE: \
  489. for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
  490. target = WireFormatLite::InternalWrite##CAMELCASE##ToArray( \
  491. number, repeated_##LOWERCASE##_value->Get(i), \
  492. deterministic, target); \
  493. } \
  494. break
  495. HANDLE_TYPE( GROUP, Group, message);
  496. HANDLE_TYPE( MESSAGE, Message, message);
  497. #undef HANDLE_TYPE
  498. }
  499. }
  500. } else if (!is_cleared) {
  501. switch (real_type(type)) {
  502. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
  503. case FieldDescriptor::TYPE_##UPPERCASE: \
  504. target = WireFormatLite::Write##CAMELCASE##ToArray( \
  505. number, VALUE, target); \
  506. break
  507. HANDLE_TYPE( INT32, Int32, int32_value);
  508. HANDLE_TYPE( INT64, Int64, int64_value);
  509. HANDLE_TYPE( UINT32, UInt32, uint32_value);
  510. HANDLE_TYPE( UINT64, UInt64, uint64_value);
  511. HANDLE_TYPE( SINT32, SInt32, int32_value);
  512. HANDLE_TYPE( SINT64, SInt64, int64_value);
  513. HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
  514. HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
  515. HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
  516. HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
  517. HANDLE_TYPE( FLOAT, Float, float_value);
  518. HANDLE_TYPE( DOUBLE, Double, double_value);
  519. HANDLE_TYPE( BOOL, Bool, bool_value);
  520. HANDLE_TYPE( STRING, String, *string_value);
  521. HANDLE_TYPE( BYTES, Bytes, *string_value);
  522. HANDLE_TYPE( ENUM, Enum, enum_value);
  523. HANDLE_TYPE( GROUP, Group, *message_value);
  524. #undef HANDLE_TYPE
  525. case FieldDescriptor::TYPE_MESSAGE:
  526. if (is_lazy) {
  527. target = lazymessage_value->InternalWriteMessageToArray(
  528. number, deterministic, target);
  529. } else {
  530. target = WireFormatLite::InternalWriteMessageToArray(
  531. number, *message_value, deterministic, target);
  532. }
  533. break;
  534. }
  535. }
  536. return target;
  537. }
  538. uint8*
  539. ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
  540. int number, bool deterministic, uint8* target) const {
  541. if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
  542. // Not a valid MessageSet extension, but serialize it the normal way.
  543. GOOGLE_LOG(WARNING) << "Invalid message set extension.";
  544. return InternalSerializeFieldWithCachedSizesToArray(number, deterministic,
  545. target);
  546. }
  547. if (is_cleared) return target;
  548. // Start group.
  549. target = io::CodedOutputStream::WriteTagToArray(
  550. WireFormatLite::kMessageSetItemStartTag, target);
  551. // Write type ID.
  552. target = WireFormatLite::WriteUInt32ToArray(
  553. WireFormatLite::kMessageSetTypeIdNumber, number, target);
  554. // Write message.
  555. if (is_lazy) {
  556. target = lazymessage_value->InternalWriteMessageToArray(
  557. WireFormatLite::kMessageSetMessageNumber, deterministic, target);
  558. } else {
  559. target = WireFormatLite::InternalWriteMessageToArray(
  560. WireFormatLite::kMessageSetMessageNumber, *message_value, deterministic,
  561. target);
  562. }
  563. // End group.
  564. target = io::CodedOutputStream::WriteTagToArray(
  565. WireFormatLite::kMessageSetItemEndTag, target);
  566. return target;
  567. }
  568. bool ExtensionSet::ParseFieldMaybeLazily(
  569. int wire_type, int field_number, io::CodedInputStream* input,
  570. ExtensionFinder* extension_finder,
  571. MessageSetFieldSkipper* field_skipper) {
  572. return ParseField(WireFormatLite::MakeTag(
  573. field_number, static_cast<WireFormatLite::WireType>(wire_type)),
  574. input, extension_finder, field_skipper);
  575. }
  576. bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
  577. ExtensionFinder* extension_finder,
  578. MessageSetFieldSkipper* field_skipper) {
  579. while (true) {
  580. const uint32 tag = input->ReadTag();
  581. switch (tag) {
  582. case 0:
  583. return true;
  584. case WireFormatLite::kMessageSetItemStartTag:
  585. if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
  586. return false;
  587. }
  588. break;
  589. default:
  590. if (!ParseField(tag, input, extension_finder, field_skipper)) {
  591. return false;
  592. }
  593. break;
  594. }
  595. }
  596. }
  597. bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
  598. const MessageLite* containing_type) {
  599. MessageSetFieldSkipper skipper(NULL);
  600. GeneratedExtensionFinder finder(containing_type);
  601. return ParseMessageSet(input, &finder, &skipper);
  602. }
  603. bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
  604. ExtensionFinder* extension_finder,
  605. MessageSetFieldSkipper* field_skipper) {
  606. // TODO(kenton): It would be nice to share code between this and
  607. // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
  608. // differences would be hard to factor out.
  609. // This method parses a group which should contain two fields:
  610. // required int32 type_id = 2;
  611. // required data message = 3;
  612. uint32 last_type_id = 0;
  613. // If we see message data before the type_id, we'll append it to this so
  614. // we can parse it later.
  615. string message_data;
  616. while (true) {
  617. const uint32 tag = input->ReadTagNoLastTag();
  618. if (tag == 0) return false;
  619. switch (tag) {
  620. case WireFormatLite::kMessageSetTypeIdTag: {
  621. uint32 type_id;
  622. if (!input->ReadVarint32(&type_id)) return false;
  623. last_type_id = type_id;
  624. if (!message_data.empty()) {
  625. // We saw some message data before the type_id. Have to parse it
  626. // now.
  627. io::CodedInputStream sub_input(
  628. reinterpret_cast<const uint8*>(message_data.data()),
  629. message_data.size());
  630. if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
  631. last_type_id, &sub_input,
  632. extension_finder, field_skipper)) {
  633. return false;
  634. }
  635. message_data.clear();
  636. }
  637. break;
  638. }
  639. case WireFormatLite::kMessageSetMessageTag: {
  640. if (last_type_id == 0) {
  641. // We haven't seen a type_id yet. Append this data to message_data.
  642. string temp;
  643. uint32 length;
  644. if (!input->ReadVarint32(&length)) return false;
  645. if (!input->ReadString(&temp, length)) return false;
  646. io::StringOutputStream output_stream(&message_data);
  647. io::CodedOutputStream coded_output(&output_stream);
  648. coded_output.WriteVarint32(length);
  649. coded_output.WriteString(temp);
  650. } else {
  651. // Already saw type_id, so we can parse this directly.
  652. if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
  653. last_type_id, input,
  654. extension_finder, field_skipper)) {
  655. return false;
  656. }
  657. }
  658. break;
  659. }
  660. case WireFormatLite::kMessageSetItemEndTag: {
  661. return true;
  662. }
  663. default: {
  664. if (!field_skipper->SkipField(input, tag)) return false;
  665. }
  666. }
  667. }
  668. }
  669. void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
  670. int number,
  671. io::CodedOutputStream* output) const {
  672. if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
  673. // Not a valid MessageSet extension, but serialize it the normal way.
  674. SerializeFieldWithCachedSizes(number, output);
  675. return;
  676. }
  677. if (is_cleared) return;
  678. // Start group.
  679. output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
  680. // Write type ID.
  681. WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
  682. number,
  683. output);
  684. // Write message.
  685. if (is_lazy) {
  686. lazymessage_value->WriteMessage(
  687. WireFormatLite::kMessageSetMessageNumber, output);
  688. } else {
  689. WireFormatLite::WriteMessageMaybeToArray(
  690. WireFormatLite::kMessageSetMessageNumber,
  691. *message_value,
  692. output);
  693. }
  694. // End group.
  695. output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
  696. }
  697. size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
  698. if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
  699. // Not a valid MessageSet extension, but compute the byte size for it the
  700. // normal way.
  701. return ByteSize(number);
  702. }
  703. if (is_cleared) return 0;
  704. size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
  705. // type_id
  706. our_size += io::CodedOutputStream::VarintSize32(number);
  707. // message
  708. size_t message_size = 0;
  709. if (is_lazy) {
  710. message_size = lazymessage_value->ByteSizeLong();
  711. } else {
  712. message_size = message_value->ByteSizeLong();
  713. }
  714. our_size += io::CodedOutputStream::VarintSize32(message_size);
  715. our_size += message_size;
  716. return our_size;
  717. }
  718. void ExtensionSet::SerializeMessageSetWithCachedSizes(
  719. io::CodedOutputStream* output) const {
  720. ForEach([output](int number, const Extension& ext) {
  721. ext.SerializeMessageSetItemWithCachedSizes(number, output);
  722. });
  723. }
  724. size_t ExtensionSet::MessageSetByteSize() const {
  725. size_t total_size = 0;
  726. ForEach([&total_size](int number, const Extension& ext) {
  727. total_size += ext.MessageSetItemByteSize(number);
  728. });
  729. return total_size;
  730. }
  731. } // namespace internal
  732. } // namespace protobuf
  733. } // namespace google