You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

extension_set.h 88 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  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. // This header is logically internal, but is made public because it is used
  35. // from protocol-compiler-generated code, which may reside in other components.
  36. #ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
  37. #define GOOGLE_PROTOBUF_EXTENSION_SET_H__
  38. #include <algorithm>
  39. #include <cassert>
  40. #include <map>
  41. #include <string>
  42. #include <utility>
  43. #include <vector>
  44. #include <google/protobuf/stubs/common.h>
  45. #include <google/protobuf/stubs/logging.h>
  46. #include <google/protobuf/io/coded_stream.h>
  47. #include <google/protobuf/port.h>
  48. #include <google/protobuf/parse_context.h>
  49. #include <google/protobuf/repeated_field.h>
  50. #include <google/protobuf/wire_format_lite.h>
  51. // clang-format off
  52. #include <google/protobuf/port_def.inc> // Must be last
  53. // clang-format on
  54. #ifdef SWIG
  55. #error "You cannot SWIG proto headers"
  56. #endif
  57. namespace google
  58. {
  59. namespace protobuf
  60. {
  61. class Arena;
  62. class Descriptor; // descriptor.h
  63. class FieldDescriptor; // descriptor.h
  64. class DescriptorPool; // descriptor.h
  65. class MessageLite; // message_lite.h
  66. class Message; // message.h
  67. class MessageFactory; // message.h
  68. class Reflection; // message.h
  69. class UnknownFieldSet; // unknown_field_set.h
  70. namespace internal
  71. {
  72. class FieldSkipper; // wire_format_lite.h
  73. enum class LazyVerifyOption;
  74. } // namespace internal
  75. } // namespace protobuf
  76. } // namespace google
  77. namespace google
  78. {
  79. namespace protobuf
  80. {
  81. namespace internal
  82. {
  83. class InternalMetadata;
  84. // Used to store values of type WireFormatLite::FieldType without having to
  85. // #include wire_format_lite.h. Also, ensures that we use only one byte to
  86. // store these values, which is important to keep the layout of
  87. // ExtensionSet::Extension small.
  88. typedef uint8_t FieldType;
  89. // A function which, given an integer value, returns true if the number
  90. // matches one of the defined values for the corresponding enum type. This
  91. // is used with RegisterEnumExtension, below.
  92. typedef bool EnumValidityFunc(int number);
  93. // Version of the above which takes an argument. This is needed to deal with
  94. // extensions that are not compiled in.
  95. typedef bool EnumValidityFuncWithArg(const void* arg, int number);
  96. // Information about a registered extension.
  97. struct ExtensionInfo
  98. {
  99. constexpr ExtensionInfo() :
  100. enum_validity_check()
  101. {
  102. }
  103. constexpr ExtensionInfo(const MessageLite* extendee, int param_number, FieldType type_param, bool isrepeated, bool ispacked, LazyEagerVerifyFnType verify_func) :
  104. message(extendee),
  105. number(param_number),
  106. type(type_param),
  107. is_repeated(isrepeated),
  108. is_packed(ispacked),
  109. enum_validity_check(),
  110. lazy_eager_verify_func(verify_func)
  111. {
  112. }
  113. const MessageLite* message = nullptr;
  114. int number = 0;
  115. FieldType type = 0;
  116. bool is_repeated = false;
  117. bool is_packed = false;
  118. struct EnumValidityCheck
  119. {
  120. EnumValidityFuncWithArg* func;
  121. const void* arg;
  122. };
  123. struct MessageInfo
  124. {
  125. const MessageLite* prototype;
  126. };
  127. union
  128. {
  129. EnumValidityCheck enum_validity_check;
  130. MessageInfo message_info;
  131. };
  132. // The descriptor for this extension, if one exists and is known. May be
  133. // nullptr. Must not be nullptr if the descriptor for the extension does not
  134. // live in the same pool as the descriptor for the containing type.
  135. const FieldDescriptor* descriptor = nullptr;
  136. // If this field is potentially lazy this function can be used as a cheap
  137. // verification of the raw bytes.
  138. // If nullptr then no verification is performed.
  139. LazyEagerVerifyFnType lazy_eager_verify_func = nullptr;
  140. };
  141. // An ExtensionFinder is an object which looks up extension definitions. It
  142. // must implement this method:
  143. //
  144. // bool Find(int number, ExtensionInfo* output);
  145. // GeneratedExtensionFinder is an ExtensionFinder which finds extensions
  146. // defined in .proto files which have been compiled into the binary.
  147. class PROTOBUF_EXPORT GeneratedExtensionFinder
  148. {
  149. public:
  150. explicit GeneratedExtensionFinder(const MessageLite* extendee) :
  151. extendee_(extendee)
  152. {
  153. }
  154. // Returns true and fills in *output if found, otherwise returns false.
  155. bool Find(int number, ExtensionInfo* output);
  156. private:
  157. const MessageLite* extendee_;
  158. };
  159. // Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
  160. // finding extensions from a DescriptorPool.
  161. // This is an internal helper class intended for use within the protocol buffer
  162. // library and generated classes. Clients should not use it directly. Instead,
  163. // use the generated accessors such as GetExtension() of the class being
  164. // extended.
  165. //
  166. // This class manages extensions for a protocol message object. The
  167. // message's HasExtension(), GetExtension(), MutableExtension(), and
  168. // ClearExtension() methods are just thin wrappers around the embedded
  169. // ExtensionSet. When parsing, if a tag number is encountered which is
  170. // inside one of the message type's extension ranges, the tag is passed
  171. // off to the ExtensionSet for parsing. Etc.
  172. class PROTOBUF_EXPORT ExtensionSet
  173. {
  174. public:
  175. constexpr ExtensionSet();
  176. explicit ExtensionSet(Arena* arena);
  177. ExtensionSet(ArenaInitialized, Arena* arena) :
  178. ExtensionSet(arena)
  179. {
  180. }
  181. ~ExtensionSet();
  182. // These are called at startup by protocol-compiler-generated code to
  183. // register known extensions. The registrations are used by ParseField()
  184. // to look up extensions for parsed field numbers. Note that dynamic parsing
  185. // does not use ParseField(); only protocol-compiler-generated parsing
  186. // methods do.
  187. static void RegisterExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, LazyEagerVerifyFnType verify_func);
  188. static void RegisterEnumExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid);
  189. static void RegisterMessageExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, const MessageLite* prototype, LazyEagerVerifyFnType verify_func);
  190. // =================================================================
  191. // Add all fields which are currently present to the given vector. This
  192. // is useful to implement Reflection::ListFields().
  193. void AppendToList(const Descriptor* extendee, const DescriptorPool* pool, std::vector<const FieldDescriptor*>* output) const;
  194. // =================================================================
  195. // Accessors
  196. //
  197. // Generated message classes include type-safe templated wrappers around
  198. // these methods. Generally you should use those rather than call these
  199. // directly, unless you are doing low-level memory management.
  200. //
  201. // When calling any of these accessors, the extension number requested
  202. // MUST exist in the DescriptorPool provided to the constructor. Otherwise,
  203. // the method will fail an assert. Normally, though, you would not call
  204. // these directly; you would either call the generated accessors of your
  205. // message class (e.g. GetExtension()) or you would call the accessors
  206. // of the reflection interface. In both cases, it is impossible to
  207. // trigger this assert failure: the generated accessors only accept
  208. // linked-in extension types as parameters, while the Reflection interface
  209. // requires you to provide the FieldDescriptor describing the extension.
  210. //
  211. // When calling any of these accessors, a protocol-compiler-generated
  212. // implementation of the extension corresponding to the number MUST
  213. // be linked in, and the FieldDescriptor used to refer to it MUST be
  214. // the one generated by that linked-in code. Otherwise, the method will
  215. // die on an assert failure. The message objects returned by the message
  216. // accessors are guaranteed to be of the correct linked-in type.
  217. //
  218. // These methods pretty much match Reflection except that:
  219. // - They're not virtual.
  220. // - They identify fields by number rather than FieldDescriptors.
  221. // - They identify enum values using integers rather than descriptors.
  222. // - Strings provide Mutable() in addition to Set() accessors.
  223. bool Has(int number) const;
  224. int ExtensionSize(int number) const; // Size of a repeated extension.
  225. int NumExtensions() const; // The number of extensions
  226. FieldType ExtensionType(int number) const;
  227. void ClearExtension(int number);
  228. // singular fields -------------------------------------------------
  229. int32_t GetInt32(int number, int32_t default_value) const;
  230. int64_t GetInt64(int number, int64_t default_value) const;
  231. uint32_t GetUInt32(int number, uint32_t default_value) const;
  232. uint64_t GetUInt64(int number, uint64_t default_value) const;
  233. float GetFloat(int number, float default_value) const;
  234. double GetDouble(int number, double default_value) const;
  235. bool GetBool(int number, bool default_value) const;
  236. int GetEnum(int number, int default_value) const;
  237. const std::string& GetString(int number, const std::string& default_value) const;
  238. const MessageLite& GetMessage(int number, const MessageLite& default_value) const;
  239. const MessageLite& GetMessage(int number, const Descriptor* message_type, MessageFactory* factory) const;
  240. // |descriptor| may be nullptr so long as it is known that the descriptor for
  241. // the extension lives in the same pool as the descriptor for the containing
  242. // type.
  243. #define desc const FieldDescriptor* descriptor // avoid line wrapping
  244. void SetInt32(int number, FieldType type, int32_t value, desc);
  245. void SetInt64(int number, FieldType type, int64_t value, desc);
  246. void SetUInt32(int number, FieldType type, uint32_t value, desc);
  247. void SetUInt64(int number, FieldType type, uint64_t value, desc);
  248. void SetFloat(int number, FieldType type, float value, desc);
  249. void SetDouble(int number, FieldType type, double value, desc);
  250. void SetBool(int number, FieldType type, bool value, desc);
  251. void SetEnum(int number, FieldType type, int value, desc);
  252. void SetString(int number, FieldType type, std::string value, desc);
  253. std::string* MutableString(int number, FieldType type, desc);
  254. MessageLite* MutableMessage(int number, FieldType type, const MessageLite& prototype, desc);
  255. MessageLite* MutableMessage(const FieldDescriptor* descriptor, MessageFactory* factory);
  256. // Adds the given message to the ExtensionSet, taking ownership of the
  257. // message object. Existing message with the same number will be deleted.
  258. // If "message" is nullptr, this is equivalent to "ClearExtension(number)".
  259. void SetAllocatedMessage(int number, FieldType type, const FieldDescriptor* descriptor, MessageLite* message);
  260. void UnsafeArenaSetAllocatedMessage(int number, FieldType type, const FieldDescriptor* descriptor, MessageLite* message);
  261. PROTOBUF_NODISCARD MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
  262. MessageLite* UnsafeArenaReleaseMessage(int number, const MessageLite& prototype);
  263. PROTOBUF_NODISCARD MessageLite* ReleaseMessage(
  264. const FieldDescriptor* descriptor, MessageFactory* factory
  265. );
  266. MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, MessageFactory* factory);
  267. #undef desc
  268. Arena* GetArena() const
  269. {
  270. return arena_;
  271. }
  272. // repeated fields -------------------------------------------------
  273. // Fetches a RepeatedField extension by number; returns |default_value|
  274. // if no such extension exists. User should not touch this directly; it is
  275. // used by the GetRepeatedExtension() method.
  276. const void* GetRawRepeatedField(int number, const void* default_value) const;
  277. // Fetches a mutable version of a RepeatedField extension by number,
  278. // instantiating one if none exists. Similar to above, user should not use
  279. // this directly; it underlies MutableRepeatedExtension().
  280. void* MutableRawRepeatedField(int number, FieldType field_type, bool packed, const FieldDescriptor* desc);
  281. // This is an overload of MutableRawRepeatedField to maintain compatibility
  282. // with old code using a previous API. This version of
  283. // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension.
  284. // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
  285. void* MutableRawRepeatedField(int number);
  286. int32_t GetRepeatedInt32(int number, int index) const;
  287. int64_t GetRepeatedInt64(int number, int index) const;
  288. uint32_t GetRepeatedUInt32(int number, int index) const;
  289. uint64_t GetRepeatedUInt64(int number, int index) const;
  290. float GetRepeatedFloat(int number, int index) const;
  291. double GetRepeatedDouble(int number, int index) const;
  292. bool GetRepeatedBool(int number, int index) const;
  293. int GetRepeatedEnum(int number, int index) const;
  294. const std::string& GetRepeatedString(int number, int index) const;
  295. const MessageLite& GetRepeatedMessage(int number, int index) const;
  296. void SetRepeatedInt32(int number, int index, int32_t value);
  297. void SetRepeatedInt64(int number, int index, int64_t value);
  298. void SetRepeatedUInt32(int number, int index, uint32_t value);
  299. void SetRepeatedUInt64(int number, int index, uint64_t value);
  300. void SetRepeatedFloat(int number, int index, float value);
  301. void SetRepeatedDouble(int number, int index, double value);
  302. void SetRepeatedBool(int number, int index, bool value);
  303. void SetRepeatedEnum(int number, int index, int value);
  304. void SetRepeatedString(int number, int index, std::string value);
  305. std::string* MutableRepeatedString(int number, int index);
  306. MessageLite* MutableRepeatedMessage(int number, int index);
  307. #define desc const FieldDescriptor* descriptor // avoid line wrapping
  308. void AddInt32(int number, FieldType type, bool packed, int32_t value, desc);
  309. void AddInt64(int number, FieldType type, bool packed, int64_t value, desc);
  310. void AddUInt32(int number, FieldType type, bool packed, uint32_t value, desc);
  311. void AddUInt64(int number, FieldType type, bool packed, uint64_t value, desc);
  312. void AddFloat(int number, FieldType type, bool packed, float value, desc);
  313. void AddDouble(int number, FieldType type, bool packed, double value, desc);
  314. void AddBool(int number, FieldType type, bool packed, bool value, desc);
  315. void AddEnum(int number, FieldType type, bool packed, int value, desc);
  316. void AddString(int number, FieldType type, std::string value, desc);
  317. std::string* AddString(int number, FieldType type, desc);
  318. MessageLite* AddMessage(int number, FieldType type, const MessageLite& prototype, desc);
  319. MessageLite* AddMessage(const FieldDescriptor* descriptor, MessageFactory* factory);
  320. void AddAllocatedMessage(const FieldDescriptor* descriptor, MessageLite* new_entry);
  321. void UnsafeArenaAddAllocatedMessage(const FieldDescriptor* descriptor, MessageLite* new_entry);
  322. #undef desc
  323. void RemoveLast(int number);
  324. PROTOBUF_NODISCARD MessageLite* ReleaseLast(int number);
  325. MessageLite* UnsafeArenaReleaseLast(int number);
  326. void SwapElements(int number, int index1, int index2);
  327. // =================================================================
  328. // convenience methods for implementing methods of Message
  329. //
  330. // These could all be implemented in terms of the other methods of this
  331. // class, but providing them here helps keep the generated code size down.
  332. void Clear();
  333. void MergeFrom(const MessageLite* extendee, const ExtensionSet& other);
  334. void Swap(const MessageLite* extendee, ExtensionSet* other);
  335. void InternalSwap(ExtensionSet* other);
  336. void SwapExtension(const MessageLite* extendee, ExtensionSet* other, int number);
  337. void UnsafeShallowSwapExtension(ExtensionSet* other, int number);
  338. bool IsInitialized() const;
  339. // Lite parser
  340. const char* ParseField(uint64_t tag, const char* ptr, const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  341. // Full parser
  342. const char* ParseField(uint64_t tag, const char* ptr, const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  343. template<typename Msg>
  344. const char* ParseMessageSet(const char* ptr, const Msg* extendee, InternalMetadata* metadata, internal::ParseContext* ctx)
  345. {
  346. struct MessageSetItem
  347. {
  348. const char* _InternalParse(const char* ptr, ParseContext* ctx)
  349. {
  350. return me->ParseMessageSetItem(ptr, extendee, metadata, ctx);
  351. }
  352. ExtensionSet* me;
  353. const Msg* extendee;
  354. InternalMetadata* metadata;
  355. } item{this, extendee, metadata};
  356. while (!ctx->Done(&ptr))
  357. {
  358. uint32_t tag;
  359. ptr = ReadTag(ptr, &tag);
  360. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  361. if (tag == WireFormatLite::kMessageSetItemStartTag)
  362. {
  363. ptr = ctx->ParseGroup(&item, ptr, tag);
  364. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  365. }
  366. else
  367. {
  368. if (tag == 0 || (tag & 7) == 4)
  369. {
  370. ctx->SetLastTag(tag);
  371. return ptr;
  372. }
  373. ptr = ParseField(tag, ptr, extendee, metadata, ctx);
  374. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  375. }
  376. }
  377. return ptr;
  378. }
  379. // Write all extension fields with field numbers in the range
  380. // [start_field_number, end_field_number)
  381. // to the output stream, using the cached sizes computed when ByteSize() was
  382. // last called. Note that the range bounds are inclusive-exclusive.
  383. void SerializeWithCachedSizes(const MessageLite* extendee, int start_field_number, int end_field_number, io::CodedOutputStream* output) const
  384. {
  385. output->SetCur(_InternalSerialize(extendee, start_field_number, end_field_number, output->Cur(), output->EpsCopy()));
  386. }
  387. // Same as SerializeWithCachedSizes, but without any bounds checking.
  388. // The caller must ensure that target has sufficient capacity for the
  389. // serialized extensions.
  390. //
  391. // Returns a pointer past the last written byte.
  392. uint8_t* _InternalSerialize(const MessageLite* extendee, int start_field_number, int end_field_number, uint8_t* target, io::EpsCopyOutputStream* stream) const
  393. {
  394. if (flat_size_ == 0)
  395. {
  396. assert(!is_large());
  397. return target;
  398. }
  399. return _InternalSerializeImpl(extendee, start_field_number, end_field_number, target, stream);
  400. }
  401. // Like above but serializes in MessageSet format.
  402. void SerializeMessageSetWithCachedSizes(const MessageLite* extendee, io::CodedOutputStream* output) const
  403. {
  404. output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray(
  405. extendee, output->Cur(), output->EpsCopy()
  406. ));
  407. }
  408. uint8_t* InternalSerializeMessageSetWithCachedSizesToArray(
  409. const MessageLite* extendee, uint8_t* target, io::EpsCopyOutputStream* stream
  410. ) const;
  411. // For backward-compatibility, versions of two of the above methods that
  412. // serialize deterministically iff SetDefaultSerializationDeterministic()
  413. // has been called.
  414. uint8_t* SerializeWithCachedSizesToArray(int start_field_number, int end_field_number, uint8_t* target) const;
  415. uint8_t* SerializeMessageSetWithCachedSizesToArray(
  416. const MessageLite* extendee, uint8_t* target
  417. ) const;
  418. // Returns the total serialized size of all the extensions.
  419. size_t ByteSize() const;
  420. // Like ByteSize() but uses MessageSet format.
  421. size_t MessageSetByteSize() const;
  422. // Returns (an estimate of) the total number of bytes used for storing the
  423. // extensions in memory, excluding sizeof(*this). If the ExtensionSet is
  424. // for a lite message (and thus possibly contains lite messages), the results
  425. // are undefined (might work, might crash, might corrupt data, might not even
  426. // be linked in). It's up to the protocol compiler to avoid calling this on
  427. // such ExtensionSets (easy enough since lite messages don't implement
  428. // SpaceUsed()).
  429. size_t SpaceUsedExcludingSelfLong() const;
  430. // This method just calls SpaceUsedExcludingSelfLong() but it can not be
  431. // inlined because the definition of SpaceUsedExcludingSelfLong() is not
  432. // included in lite runtime and when an inline method refers to it MSVC
  433. // will complain about unresolved symbols when building the lite runtime
  434. // as .dll.
  435. int SpaceUsedExcludingSelf() const;
  436. private:
  437. template<typename Type>
  438. friend class PrimitiveTypeTraits;
  439. template<typename Type>
  440. friend class RepeatedPrimitiveTypeTraits;
  441. template<typename Type, bool IsValid(int)>
  442. friend class EnumTypeTraits;
  443. template<typename Type, bool IsValid(int)>
  444. friend class RepeatedEnumTypeTraits;
  445. friend class google::protobuf::Reflection;
  446. const int32_t& GetRefInt32(int number, const int32_t& default_value) const;
  447. const int64_t& GetRefInt64(int number, const int64_t& default_value) const;
  448. const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const;
  449. const uint64_t& GetRefUInt64(int number, const uint64_t& default_value) const;
  450. const float& GetRefFloat(int number, const float& default_value) const;
  451. const double& GetRefDouble(int number, const double& default_value) const;
  452. const bool& GetRefBool(int number, const bool& default_value) const;
  453. const int& GetRefEnum(int number, const int& default_value) const;
  454. const int32_t& GetRefRepeatedInt32(int number, int index) const;
  455. const int64_t& GetRefRepeatedInt64(int number, int index) const;
  456. const uint32_t& GetRefRepeatedUInt32(int number, int index) const;
  457. const uint64_t& GetRefRepeatedUInt64(int number, int index) const;
  458. const float& GetRefRepeatedFloat(int number, int index) const;
  459. const double& GetRefRepeatedDouble(int number, int index) const;
  460. const bool& GetRefRepeatedBool(int number, int index) const;
  461. const int& GetRefRepeatedEnum(int number, int index) const;
  462. // Implementation of _InternalSerialize for non-empty map_.
  463. uint8_t* _InternalSerializeImpl(const MessageLite* extendee, int start_field_number, int end_field_number, uint8_t* target, io::EpsCopyOutputStream* stream) const;
  464. // Interface of a lazily parsed singular message extension.
  465. class PROTOBUF_EXPORT LazyMessageExtension
  466. {
  467. public:
  468. LazyMessageExtension()
  469. {
  470. }
  471. virtual ~LazyMessageExtension()
  472. {
  473. }
  474. virtual LazyMessageExtension* New(Arena* arena) const = 0;
  475. virtual const MessageLite& GetMessage(const MessageLite& prototype, Arena* arena) const = 0;
  476. virtual MessageLite* MutableMessage(const MessageLite& prototype, Arena* arena) = 0;
  477. virtual void SetAllocatedMessage(MessageLite* message, Arena* arena) = 0;
  478. virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message, Arena* arena) = 0;
  479. PROTOBUF_NODISCARD virtual MessageLite* ReleaseMessage(
  480. const MessageLite& prototype, Arena* arena
  481. ) = 0;
  482. virtual MessageLite* UnsafeArenaReleaseMessage(const MessageLite& prototype, Arena* arena) = 0;
  483. virtual bool IsInitialized() const = 0;
  484. PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead")
  485. virtual int ByteSize() const
  486. {
  487. return internal::ToIntSize(ByteSizeLong());
  488. }
  489. virtual size_t ByteSizeLong() const = 0;
  490. virtual size_t SpaceUsedLong() const = 0;
  491. virtual void MergeFrom(const MessageLite* prototype, const LazyMessageExtension& other, Arena* arena) = 0;
  492. virtual void MergeFromMessage(const MessageLite& msg, Arena* arena) = 0;
  493. virtual void Clear() = 0;
  494. virtual const char* _InternalParse(const Message& prototype, Arena* arena, LazyVerifyOption option, const char* ptr, ParseContext* ctx) = 0;
  495. virtual uint8_t* WriteMessageToArray(
  496. const MessageLite* prototype, int number, uint8_t* target, io::EpsCopyOutputStream* stream
  497. ) const = 0;
  498. private:
  499. virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable.
  500. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
  501. };
  502. // Give access to function defined below to see LazyMessageExtension.
  503. friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena);
  504. struct Extension
  505. {
  506. // The order of these fields packs Extension into 24 bytes when using 8
  507. // byte alignment. Consider this when adding or removing fields here.
  508. union
  509. {
  510. int32_t int32_t_value;
  511. int64_t int64_t_value;
  512. uint32_t uint32_t_value;
  513. uint64_t uint64_t_value;
  514. float float_value;
  515. double double_value;
  516. bool bool_value;
  517. int enum_value;
  518. std::string* string_value;
  519. MessageLite* message_value;
  520. LazyMessageExtension* lazymessage_value;
  521. RepeatedField<int32_t>* repeated_int32_t_value;
  522. RepeatedField<int64_t>* repeated_int64_t_value;
  523. RepeatedField<uint32_t>* repeated_uint32_t_value;
  524. RepeatedField<uint64_t>* repeated_uint64_t_value;
  525. RepeatedField<float>* repeated_float_value;
  526. RepeatedField<double>* repeated_double_value;
  527. RepeatedField<bool>* repeated_bool_value;
  528. RepeatedField<int>* repeated_enum_value;
  529. RepeatedPtrField<std::string>* repeated_string_value;
  530. RepeatedPtrField<MessageLite>* repeated_message_value;
  531. };
  532. FieldType type;
  533. bool is_repeated;
  534. // For singular types, indicates if the extension is "cleared". This
  535. // happens when an extension is set and then later cleared by the caller.
  536. // We want to keep the Extension object around for reuse, so instead of
  537. // removing it from the map, we just set is_cleared = true. This has no
  538. // meaning for repeated types; for those, the size of the RepeatedField
  539. // simply becomes zero when cleared.
  540. bool is_cleared : 4;
  541. // For singular message types, indicates whether lazy parsing is enabled
  542. // for this extension. This field is only valid when type == TYPE_MESSAGE
  543. // and !is_repeated because we only support lazy parsing for singular
  544. // message types currently. If is_lazy = true, the extension is stored in
  545. // lazymessage_value. Otherwise, the extension will be message_value.
  546. bool is_lazy : 4;
  547. // For repeated types, this indicates if the [packed=true] option is set.
  548. bool is_packed;
  549. // For packed fields, the size of the packed data is recorded here when
  550. // ByteSize() is called then used during serialization.
  551. // TODO(kenton): Use atomic<int> when C++ supports it.
  552. mutable int cached_size;
  553. // The descriptor for this extension, if one exists and is known. May be
  554. // nullptr. Must not be nullptr if the descriptor for the extension does
  555. // not live in the same pool as the descriptor for the containing type.
  556. const FieldDescriptor* descriptor;
  557. // Some helper methods for operations on a single Extension.
  558. uint8_t* InternalSerializeFieldWithCachedSizesToArray(
  559. const MessageLite* extendee, const ExtensionSet* extension_set, int number, uint8_t* target, io::EpsCopyOutputStream* stream
  560. ) const;
  561. uint8_t* InternalSerializeMessageSetItemWithCachedSizesToArray(
  562. const MessageLite* extendee, const ExtensionSet* extension_set, int number, uint8_t* target, io::EpsCopyOutputStream* stream
  563. ) const;
  564. size_t ByteSize(int number) const;
  565. size_t MessageSetItemByteSize(int number) const;
  566. void Clear();
  567. int GetSize() const;
  568. void Free();
  569. size_t SpaceUsedExcludingSelfLong() const;
  570. bool IsInitialized() const;
  571. };
  572. // The Extension struct is small enough to be passed by value, so we use it
  573. // directly as the value type in mappings rather than use pointers. We use
  574. // sorted maps rather than hash-maps because we expect most ExtensionSets will
  575. // only contain a small number of extension. Also, we want AppendToList and
  576. // deterministic serialization to order fields by field number.
  577. struct KeyValue
  578. {
  579. int first;
  580. Extension second;
  581. struct FirstComparator
  582. {
  583. bool operator()(const KeyValue& lhs, const KeyValue& rhs) const
  584. {
  585. return lhs.first < rhs.first;
  586. }
  587. bool operator()(const KeyValue& lhs, int key) const
  588. {
  589. return lhs.first < key;
  590. }
  591. bool operator()(int key, const KeyValue& rhs) const
  592. {
  593. return key < rhs.first;
  594. }
  595. };
  596. };
  597. typedef std::map<int, Extension> LargeMap;
  598. // Wrapper API that switches between flat-map and LargeMap.
  599. // Finds a key (if present) in the ExtensionSet.
  600. const Extension* FindOrNull(int key) const;
  601. Extension* FindOrNull(int key);
  602. // Helper-functions that only inspect the LargeMap.
  603. const Extension* FindOrNullInLargeMap(int key) const;
  604. Extension* FindOrNullInLargeMap(int key);
  605. // Inserts a new (key, Extension) into the ExtensionSet (and returns true), or
  606. // finds the already-existing Extension for that key (returns false).
  607. // The Extension* will point to the new-or-found Extension.
  608. std::pair<Extension*, bool> Insert(int key);
  609. // Grows the flat_capacity_.
  610. // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap.
  611. void GrowCapacity(size_t minimum_new_capacity);
  612. static constexpr uint16_t kMaximumFlatCapacity = 256;
  613. bool is_large() const
  614. {
  615. return static_cast<int16_t>(flat_size_) < 0;
  616. }
  617. // Removes a key from the ExtensionSet.
  618. void Erase(int key);
  619. size_t Size() const
  620. {
  621. return PROTOBUF_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_;
  622. }
  623. // Similar to std::for_each.
  624. // Each Iterator is decomposed into ->first and ->second fields, so
  625. // that the KeyValueFunctor can be agnostic vis-a-vis KeyValue-vs-std::pair.
  626. template<typename Iterator, typename KeyValueFunctor>
  627. static KeyValueFunctor ForEach(Iterator begin, Iterator end, KeyValueFunctor func)
  628. {
  629. for (Iterator it = begin; it != end; ++it)
  630. func(it->first, it->second);
  631. return std::move(func);
  632. }
  633. // Applies a functor to the <int, Extension&> pairs in sorted order.
  634. template<typename KeyValueFunctor>
  635. KeyValueFunctor ForEach(KeyValueFunctor func)
  636. {
  637. if (PROTOBUF_PREDICT_FALSE(is_large()))
  638. {
  639. return ForEach(map_.large->begin(), map_.large->end(), std::move(func));
  640. }
  641. return ForEach(flat_begin(), flat_end(), std::move(func));
  642. }
  643. // Applies a functor to the <int, const Extension&> pairs in sorted order.
  644. template<typename KeyValueFunctor>
  645. KeyValueFunctor ForEach(KeyValueFunctor func) const
  646. {
  647. if (PROTOBUF_PREDICT_FALSE(is_large()))
  648. {
  649. return ForEach(map_.large->begin(), map_.large->end(), std::move(func));
  650. }
  651. return ForEach(flat_begin(), flat_end(), std::move(func));
  652. }
  653. // Merges existing Extension from other_extension
  654. void InternalExtensionMergeFrom(const MessageLite* extendee, int number, const Extension& other_extension, Arena* other_arena);
  655. inline static bool is_packable(WireFormatLite::WireType type)
  656. {
  657. switch (type)
  658. {
  659. case WireFormatLite::WIRETYPE_VARINT:
  660. case WireFormatLite::WIRETYPE_FIXED64:
  661. case WireFormatLite::WIRETYPE_FIXED32:
  662. return true;
  663. case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
  664. case WireFormatLite::WIRETYPE_START_GROUP:
  665. case WireFormatLite::WIRETYPE_END_GROUP:
  666. return false;
  667. // Do not add a default statement. Let the compiler complain when
  668. // someone
  669. // adds a new wire type.
  670. }
  671. PROTOBUF_ASSUME(false); // switch handles all possible enum values
  672. return false;
  673. }
  674. // Returns true and fills field_number and extension if extension is found.
  675. // Note to support packed repeated field compatibility, it also fills whether
  676. // the tag on wire is packed, which can be different from
  677. // extension->is_packed (whether packed=true is specified).
  678. template<typename ExtensionFinder>
  679. bool FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder, int* field_number, ExtensionInfo* extension, bool* was_packed_on_wire)
  680. {
  681. *field_number = WireFormatLite::GetTagFieldNumber(tag);
  682. WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
  683. return FindExtensionInfoFromFieldNumber(wire_type, *field_number, extension_finder, extension, was_packed_on_wire);
  684. }
  685. // Returns true and fills extension if extension is found.
  686. // Note to support packed repeated field compatibility, it also fills whether
  687. // the tag on wire is packed, which can be different from
  688. // extension->is_packed (whether packed=true is specified).
  689. template<typename ExtensionFinder>
  690. bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number, ExtensionFinder* extension_finder, ExtensionInfo* extension, bool* was_packed_on_wire) const
  691. {
  692. if (!extension_finder->Find(field_number, extension))
  693. {
  694. return false;
  695. }
  696. GOOGLE_DCHECK(extension->type > 0 && extension->type <= WireFormatLite::MAX_FIELD_TYPE);
  697. auto real_type = static_cast<WireFormatLite::FieldType>(extension->type);
  698. WireFormatLite::WireType expected_wire_type =
  699. WireFormatLite::WireTypeForFieldType(real_type);
  700. // Check if this is a packed field.
  701. *was_packed_on_wire = false;
  702. if (extension->is_repeated &&
  703. wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
  704. is_packable(expected_wire_type))
  705. {
  706. *was_packed_on_wire = true;
  707. return true;
  708. }
  709. // Otherwise the wire type must match.
  710. return expected_wire_type == wire_type;
  711. }
  712. // Find the prototype for a LazyMessage from the extension registry. Returns
  713. // null if the extension is not found.
  714. const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee, int number) const;
  715. // Returns true if extension is present and lazy.
  716. bool HasLazy(int number) const;
  717. // Gets the extension with the given number, creating it if it does not
  718. // already exist. Returns true if the extension did not already exist.
  719. bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, Extension** result);
  720. // Gets the repeated extension for the given descriptor, creating it if
  721. // it does not exist.
  722. Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor);
  723. bool FindExtension(int wire_type, uint32_t field, const MessageLite* extendee, const internal::ParseContext* /*ctx*/, ExtensionInfo* extension, bool* was_packed_on_wire)
  724. {
  725. GeneratedExtensionFinder finder(extendee);
  726. return FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension, was_packed_on_wire);
  727. }
  728. inline bool FindExtension(int wire_type, uint32_t field, const Message* extendee, const internal::ParseContext* ctx, ExtensionInfo* extension, bool* was_packed_on_wire);
  729. // Used for MessageSet only
  730. const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx)
  731. {
  732. // Lite MessageSet doesn't implement lazy.
  733. return ParseField(tag, ptr, extendee, metadata, ctx);
  734. }
  735. const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  736. const char* ParseMessageSetItem(const char* ptr, const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  737. const char* ParseMessageSetItem(const char* ptr, const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  738. // Implemented in extension_set_inl.h to keep code out of the header file.
  739. template<typename T>
  740. const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire, const ExtensionInfo& info, internal::InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx);
  741. template<typename Msg, typename T>
  742. const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx);
  743. // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
  744. // friendship should automatically extend to ExtensionSet::Extension, but
  745. // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
  746. // correctly. So, we must provide helpers for calling methods of that
  747. // class.
  748. // Defined in extension_set_heavy.cc.
  749. static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong(
  750. RepeatedPtrFieldBase* field
  751. );
  752. KeyValue* flat_begin()
  753. {
  754. assert(!is_large());
  755. return map_.flat;
  756. }
  757. const KeyValue* flat_begin() const
  758. {
  759. assert(!is_large());
  760. return map_.flat;
  761. }
  762. KeyValue* flat_end()
  763. {
  764. assert(!is_large());
  765. return map_.flat + flat_size_;
  766. }
  767. const KeyValue* flat_end() const
  768. {
  769. assert(!is_large());
  770. return map_.flat + flat_size_;
  771. }
  772. Arena* arena_;
  773. // Manual memory-management:
  774. // map_.flat is an allocated array of flat_capacity_ elements.
  775. // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix.
  776. uint16_t flat_capacity_;
  777. uint16_t flat_size_; // negative int16_t(flat_size_) indicates is_large()
  778. union AllocatedData
  779. {
  780. KeyValue* flat;
  781. // If flat_capacity_ > kMaximumFlatCapacity, switch to LargeMap,
  782. // which guarantees O(n lg n) CPU but larger constant factors.
  783. LargeMap* large;
  784. } map_;
  785. static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity);
  786. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
  787. };
  788. constexpr ExtensionSet::ExtensionSet() :
  789. arena_(nullptr),
  790. flat_capacity_(0),
  791. flat_size_(0),
  792. map_{nullptr}
  793. {
  794. }
  795. // These are just for convenience...
  796. inline void ExtensionSet::SetString(int number, FieldType type, std::string value, const FieldDescriptor* descriptor)
  797. {
  798. MutableString(number, type, descriptor)->assign(std::move(value));
  799. }
  800. inline void ExtensionSet::SetRepeatedString(int number, int index, std::string value)
  801. {
  802. MutableRepeatedString(number, index)->assign(std::move(value));
  803. }
  804. inline void ExtensionSet::AddString(int number, FieldType type, std::string value, const FieldDescriptor* descriptor)
  805. {
  806. AddString(number, type, descriptor)->assign(std::move(value));
  807. }
  808. // ===================================================================
  809. // Glue for generated extension accessors
  810. // -------------------------------------------------------------------
  811. // Template magic
  812. // First we have a set of classes representing "type traits" for different
  813. // field types. A type traits class knows how to implement basic accessors
  814. // for extensions of a particular type given an ExtensionSet. The signature
  815. // for a type traits class looks like this:
  816. //
  817. // class TypeTraits {
  818. // public:
  819. // typedef ? ConstType;
  820. // typedef ? MutableType;
  821. // // TypeTraits for singular fields and repeated fields will define the
  822. // // symbol "Singular" or "Repeated" respectively. These two symbols will
  823. // // be used in extension accessors to distinguish between singular
  824. // // extensions and repeated extensions. If the TypeTraits for the passed
  825. // // in extension doesn't have the expected symbol defined, it means the
  826. // // user is passing a repeated extension to a singular accessor, or the
  827. // // opposite. In that case the C++ compiler will generate an error
  828. // // message "no matching member function" to inform the user.
  829. // typedef ? Singular
  830. // typedef ? Repeated
  831. //
  832. // static inline ConstType Get(int number, const ExtensionSet& set);
  833. // static inline void Set(int number, ConstType value, ExtensionSet* set);
  834. // static inline MutableType Mutable(int number, ExtensionSet* set);
  835. //
  836. // // Variants for repeated fields.
  837. // static inline ConstType Get(int number, const ExtensionSet& set,
  838. // int index);
  839. // static inline void Set(int number, int index,
  840. // ConstType value, ExtensionSet* set);
  841. // static inline MutableType Mutable(int number, int index,
  842. // ExtensionSet* set);
  843. // static inline void Add(int number, ConstType value, ExtensionSet* set);
  844. // static inline MutableType Add(int number, ExtensionSet* set);
  845. // This is used by the ExtensionIdentifier constructor to register
  846. // the extension at dynamic initialization.
  847. // template <typename ExtendeeT>
  848. // static void Register(int number, FieldType type, bool is_packed);
  849. // };
  850. //
  851. // Not all of these methods make sense for all field types. For example, the
  852. // "Mutable" methods only make sense for strings and messages, and the
  853. // repeated methods only make sense for repeated types. So, each type
  854. // traits class implements only the set of methods from this signature that it
  855. // actually supports. This will cause a compiler error if the user tries to
  856. // access an extension using a method that doesn't make sense for its type.
  857. // For example, if "foo" is an extension of type "optional int32", then if you
  858. // try to write code like:
  859. // my_message.MutableExtension(foo)
  860. // you will get a compile error because PrimitiveTypeTraits<int32_t> does not
  861. // have a "Mutable()" method.
  862. // -------------------------------------------------------------------
  863. // PrimitiveTypeTraits
  864. // Since the ExtensionSet has different methods for each primitive type,
  865. // we must explicitly define the methods of the type traits class for each
  866. // known type.
  867. template<typename Type>
  868. class PrimitiveTypeTraits
  869. {
  870. public:
  871. typedef Type ConstType;
  872. typedef Type MutableType;
  873. typedef PrimitiveTypeTraits<Type> Singular;
  874. static inline ConstType Get(int number, const ExtensionSet& set, ConstType default_value);
  875. static inline const ConstType* GetPtr(int number, const ExtensionSet& set, const ConstType& default_value);
  876. static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set);
  877. template<typename ExtendeeT>
  878. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType verify_func)
  879. {
  880. ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, type, false, is_packed, verify_func);
  881. }
  882. };
  883. template<typename Type>
  884. class RepeatedPrimitiveTypeTraits
  885. {
  886. public:
  887. typedef Type ConstType;
  888. typedef Type MutableType;
  889. typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
  890. typedef RepeatedField<Type> RepeatedFieldType;
  891. static inline Type Get(int number, const ExtensionSet& set, int index);
  892. static inline const Type* GetPtr(int number, const ExtensionSet& set, int index);
  893. static inline const RepeatedField<ConstType>* GetRepeatedPtr(
  894. int number, const ExtensionSet& set
  895. );
  896. static inline void Set(int number, int index, Type value, ExtensionSet* set);
  897. static inline void Add(int number, FieldType field_type, bool is_packed, Type value, ExtensionSet* set);
  898. static inline const RepeatedField<ConstType>& GetRepeated(
  899. int number, const ExtensionSet& set
  900. );
  901. static inline RepeatedField<Type>* MutableRepeated(int number, FieldType field_type, bool is_packed, ExtensionSet* set);
  902. static const RepeatedFieldType* GetDefaultRepeatedField();
  903. template<typename ExtendeeT>
  904. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType verify_func)
  905. {
  906. ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, type, true, is_packed, verify_func);
  907. }
  908. };
  909. class PROTOBUF_EXPORT RepeatedPrimitiveDefaults
  910. {
  911. private:
  912. template<typename Type>
  913. friend class RepeatedPrimitiveTypeTraits;
  914. static const RepeatedPrimitiveDefaults* default_instance();
  915. RepeatedField<int32_t> default_repeated_field_int32_t_;
  916. RepeatedField<int64_t> default_repeated_field_int64_t_;
  917. RepeatedField<uint32_t> default_repeated_field_uint32_t_;
  918. RepeatedField<uint64_t> default_repeated_field_uint64_t_;
  919. RepeatedField<double> default_repeated_field_double_;
  920. RepeatedField<float> default_repeated_field_float_;
  921. RepeatedField<bool> default_repeated_field_bool_;
  922. };
  923. #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \
  924. template<> \
  925. inline TYPE PrimitiveTypeTraits<TYPE>::Get( \
  926. int number, const ExtensionSet& set, TYPE default_value \
  927. ) \
  928. { \
  929. return set.Get##METHOD(number, default_value); \
  930. } \
  931. template<> \
  932. inline const TYPE* PrimitiveTypeTraits<TYPE>::GetPtr( \
  933. int number, const ExtensionSet& set, const TYPE& default_value \
  934. ) \
  935. { \
  936. return &set.GetRef##METHOD(number, default_value); \
  937. } \
  938. template<> \
  939. inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, TYPE value, ExtensionSet* set) \
  940. { \
  941. set->Set##METHOD(number, field_type, value, nullptr); \
  942. } \
  943. \
  944. template<> \
  945. inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \
  946. int number, const ExtensionSet& set, int index \
  947. ) \
  948. { \
  949. return set.GetRepeated##METHOD(number, index); \
  950. } \
  951. template<> \
  952. inline const TYPE* RepeatedPrimitiveTypeTraits<TYPE>::GetPtr( \
  953. int number, const ExtensionSet& set, int index \
  954. ) \
  955. { \
  956. return &set.GetRefRepeated##METHOD(number, index); \
  957. } \
  958. template<> \
  959. inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \
  960. int number, int index, TYPE value, ExtensionSet* set \
  961. ) \
  962. { \
  963. set->SetRepeated##METHOD(number, index, value); \
  964. } \
  965. template<> \
  966. inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
  967. int number, FieldType field_type, bool is_packed, TYPE value, ExtensionSet* set \
  968. ) \
  969. { \
  970. set->Add##METHOD(number, field_type, is_packed, value, nullptr); \
  971. } \
  972. template<> \
  973. inline const RepeatedField<TYPE>* \
  974. RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() \
  975. { \
  976. return &RepeatedPrimitiveDefaults::default_instance() \
  977. ->default_repeated_field_##TYPE##_; \
  978. } \
  979. template<> \
  980. inline const RepeatedField<TYPE>& \
  981. RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number, const ExtensionSet& set) \
  982. { \
  983. return *reinterpret_cast<const RepeatedField<TYPE>*>( \
  984. set.GetRawRepeatedField(number, GetDefaultRepeatedField()) \
  985. ); \
  986. } \
  987. template<> \
  988. inline const RepeatedField<TYPE>* \
  989. RepeatedPrimitiveTypeTraits<TYPE>::GetRepeatedPtr(int number, const ExtensionSet& set) \
  990. { \
  991. return &GetRepeated(number, set); \
  992. } \
  993. template<> \
  994. inline RepeatedField<TYPE>* \
  995. RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated( \
  996. int number, FieldType field_type, bool is_packed, ExtensionSet* set \
  997. ) \
  998. { \
  999. return reinterpret_cast<RepeatedField<TYPE>*>( \
  1000. set->MutableRawRepeatedField(number, field_type, is_packed, nullptr) \
  1001. ); \
  1002. }
  1003. PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32_t, Int32)
  1004. PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64_t, Int64)
  1005. PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32_t, UInt32)
  1006. PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64_t, UInt64)
  1007. PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float)
  1008. PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
  1009. PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool)
  1010. #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
  1011. // -------------------------------------------------------------------
  1012. // StringTypeTraits
  1013. // Strings support both Set() and Mutable().
  1014. class PROTOBUF_EXPORT StringTypeTraits
  1015. {
  1016. public:
  1017. typedef const std::string& ConstType;
  1018. typedef std::string* MutableType;
  1019. typedef StringTypeTraits Singular;
  1020. static inline const std::string& Get(int number, const ExtensionSet& set, ConstType default_value)
  1021. {
  1022. return set.GetString(number, default_value);
  1023. }
  1024. static inline const std::string* GetPtr(int number, const ExtensionSet& set, ConstType default_value)
  1025. {
  1026. return &Get(number, set, default_value);
  1027. }
  1028. static inline void Set(int number, FieldType field_type, const std::string& value, ExtensionSet* set)
  1029. {
  1030. set->SetString(number, field_type, value, nullptr);
  1031. }
  1032. static inline std::string* Mutable(int number, FieldType field_type, ExtensionSet* set)
  1033. {
  1034. return set->MutableString(number, field_type, nullptr);
  1035. }
  1036. template<typename ExtendeeT>
  1037. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType verify_func)
  1038. {
  1039. ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, type, false, is_packed, verify_func);
  1040. }
  1041. };
  1042. class PROTOBUF_EXPORT RepeatedStringTypeTraits
  1043. {
  1044. public:
  1045. typedef const std::string& ConstType;
  1046. typedef std::string* MutableType;
  1047. typedef RepeatedStringTypeTraits Repeated;
  1048. typedef RepeatedPtrField<std::string> RepeatedFieldType;
  1049. static inline const std::string& Get(int number, const ExtensionSet& set, int index)
  1050. {
  1051. return set.GetRepeatedString(number, index);
  1052. }
  1053. static inline const std::string* GetPtr(int number, const ExtensionSet& set, int index)
  1054. {
  1055. return &Get(number, set, index);
  1056. }
  1057. static inline const RepeatedPtrField<std::string>* GetRepeatedPtr(
  1058. int number, const ExtensionSet& set
  1059. )
  1060. {
  1061. return &GetRepeated(number, set);
  1062. }
  1063. static inline void Set(int number, int index, const std::string& value, ExtensionSet* set)
  1064. {
  1065. set->SetRepeatedString(number, index, value);
  1066. }
  1067. static inline std::string* Mutable(int number, int index, ExtensionSet* set)
  1068. {
  1069. return set->MutableRepeatedString(number, index);
  1070. }
  1071. static inline void Add(int number, FieldType field_type, bool /*is_packed*/, const std::string& value, ExtensionSet* set)
  1072. {
  1073. set->AddString(number, field_type, value, nullptr);
  1074. }
  1075. static inline std::string* Add(int number, FieldType field_type, ExtensionSet* set)
  1076. {
  1077. return set->AddString(number, field_type, nullptr);
  1078. }
  1079. static inline const RepeatedPtrField<std::string>& GetRepeated(
  1080. int number, const ExtensionSet& set
  1081. )
  1082. {
  1083. return *reinterpret_cast<const RepeatedPtrField<std::string>*>(
  1084. set.GetRawRepeatedField(number, GetDefaultRepeatedField())
  1085. );
  1086. }
  1087. static inline RepeatedPtrField<std::string>* MutableRepeated(
  1088. int number, FieldType field_type, bool is_packed, ExtensionSet* set
  1089. )
  1090. {
  1091. return reinterpret_cast<RepeatedPtrField<std::string>*>(
  1092. set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)
  1093. );
  1094. }
  1095. static const RepeatedFieldType* GetDefaultRepeatedField();
  1096. template<typename ExtendeeT>
  1097. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType fn)
  1098. {
  1099. ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, type, true, is_packed, fn);
  1100. }
  1101. private:
  1102. static void InitializeDefaultRepeatedFields();
  1103. static void DestroyDefaultRepeatedFields();
  1104. };
  1105. // -------------------------------------------------------------------
  1106. // EnumTypeTraits
  1107. // ExtensionSet represents enums using integers internally, so we have to
  1108. // static_cast around.
  1109. template<typename Type, bool IsValid(int)>
  1110. class EnumTypeTraits
  1111. {
  1112. public:
  1113. typedef Type ConstType;
  1114. typedef Type MutableType;
  1115. typedef EnumTypeTraits<Type, IsValid> Singular;
  1116. static inline ConstType Get(int number, const ExtensionSet& set, ConstType default_value)
  1117. {
  1118. return static_cast<Type>(set.GetEnum(number, default_value));
  1119. }
  1120. static inline const ConstType* GetPtr(int number, const ExtensionSet& set, const ConstType& default_value)
  1121. {
  1122. return reinterpret_cast<const Type*>(
  1123. &set.GetRefEnum(number, default_value)
  1124. );
  1125. }
  1126. static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set)
  1127. {
  1128. GOOGLE_DCHECK(IsValid(value));
  1129. set->SetEnum(number, field_type, value, nullptr);
  1130. }
  1131. template<typename ExtendeeT>
  1132. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType fn)
  1133. {
  1134. ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, type, false, is_packed, IsValid);
  1135. }
  1136. };
  1137. template<typename Type, bool IsValid(int)>
  1138. class RepeatedEnumTypeTraits
  1139. {
  1140. public:
  1141. typedef Type ConstType;
  1142. typedef Type MutableType;
  1143. typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
  1144. typedef RepeatedField<Type> RepeatedFieldType;
  1145. static inline ConstType Get(int number, const ExtensionSet& set, int index)
  1146. {
  1147. return static_cast<Type>(set.GetRepeatedEnum(number, index));
  1148. }
  1149. static inline const ConstType* GetPtr(int number, const ExtensionSet& set, int index)
  1150. {
  1151. return reinterpret_cast<const Type*>(
  1152. &set.GetRefRepeatedEnum(number, index)
  1153. );
  1154. }
  1155. static inline void Set(int number, int index, ConstType value, ExtensionSet* set)
  1156. {
  1157. GOOGLE_DCHECK(IsValid(value));
  1158. set->SetRepeatedEnum(number, index, value);
  1159. }
  1160. static inline void Add(int number, FieldType field_type, bool is_packed, ConstType value, ExtensionSet* set)
  1161. {
  1162. GOOGLE_DCHECK(IsValid(value));
  1163. set->AddEnum(number, field_type, is_packed, value, nullptr);
  1164. }
  1165. static inline const RepeatedField<Type>& GetRepeated(
  1166. int number, const ExtensionSet& set
  1167. )
  1168. {
  1169. // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
  1170. // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
  1171. // so we need to do some casting magic. See message.h for similar
  1172. // contortions for non-extension fields.
  1173. return *reinterpret_cast<const RepeatedField<Type>*>(
  1174. set.GetRawRepeatedField(number, GetDefaultRepeatedField())
  1175. );
  1176. }
  1177. static inline const RepeatedField<Type>* GetRepeatedPtr(
  1178. int number, const ExtensionSet& set
  1179. )
  1180. {
  1181. return &GetRepeated(number, set);
  1182. }
  1183. static inline RepeatedField<Type>* MutableRepeated(int number, FieldType field_type, bool is_packed, ExtensionSet* set)
  1184. {
  1185. return reinterpret_cast<RepeatedField<Type>*>(
  1186. set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)
  1187. );
  1188. }
  1189. static const RepeatedFieldType* GetDefaultRepeatedField()
  1190. {
  1191. // Hack: as noted above, repeated enum fields are internally stored as a
  1192. // RepeatedField<int>. We need to be able to instantiate global static
  1193. // objects to return as default (empty) repeated fields on non-existent
  1194. // extensions. We would not be able to know a-priori all of the enum types
  1195. // (values of |Type|) to instantiate all of these, so we just re-use
  1196. // int32_t's default repeated field object.
  1197. return reinterpret_cast<const RepeatedField<Type>*>(
  1198. RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField()
  1199. );
  1200. }
  1201. template<typename ExtendeeT>
  1202. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType fn)
  1203. {
  1204. ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, type, true, is_packed, IsValid);
  1205. }
  1206. };
  1207. // -------------------------------------------------------------------
  1208. // MessageTypeTraits
  1209. // ExtensionSet guarantees that when manipulating extensions with message
  1210. // types, the implementation used will be the compiled-in class representing
  1211. // that type. So, we can static_cast down to the exact type we expect.
  1212. template<typename Type>
  1213. class MessageTypeTraits
  1214. {
  1215. public:
  1216. typedef const Type& ConstType;
  1217. typedef Type* MutableType;
  1218. typedef MessageTypeTraits<Type> Singular;
  1219. static inline ConstType Get(int number, const ExtensionSet& set, ConstType default_value)
  1220. {
  1221. return static_cast<const Type&>(set.GetMessage(number, default_value));
  1222. }
  1223. static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */, ConstType /* default_value */)
  1224. {
  1225. // Cannot be implemented because of forward declared messages?
  1226. return nullptr;
  1227. }
  1228. static inline MutableType Mutable(int number, FieldType field_type, ExtensionSet* set)
  1229. {
  1230. return static_cast<Type*>(set->MutableMessage(
  1231. number, field_type, Type::default_instance(), nullptr
  1232. ));
  1233. }
  1234. static inline void SetAllocated(int number, FieldType field_type, MutableType message, ExtensionSet* set)
  1235. {
  1236. set->SetAllocatedMessage(number, field_type, nullptr, message);
  1237. }
  1238. static inline void UnsafeArenaSetAllocated(int number, FieldType field_type, MutableType message, ExtensionSet* set)
  1239. {
  1240. set->UnsafeArenaSetAllocatedMessage(number, field_type, nullptr, message);
  1241. }
  1242. PROTOBUF_NODISCARD static inline MutableType Release(
  1243. int number, FieldType /* field_type */, ExtensionSet* set
  1244. )
  1245. {
  1246. return static_cast<Type*>(
  1247. set->ReleaseMessage(number, Type::default_instance())
  1248. );
  1249. }
  1250. static inline MutableType UnsafeArenaRelease(int number, FieldType /* field_type */, ExtensionSet* set)
  1251. {
  1252. return static_cast<Type*>(
  1253. set->UnsafeArenaReleaseMessage(number, Type::default_instance())
  1254. );
  1255. }
  1256. template<typename ExtendeeT>
  1257. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType fn)
  1258. {
  1259. ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), number, type, false, is_packed, &Type::default_instance(), fn);
  1260. }
  1261. };
  1262. // Used by WireFormatVerify to extract the verify function from the registry.
  1263. LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn(
  1264. const MessageLite* extendee, int number
  1265. );
  1266. // forward declaration.
  1267. class RepeatedMessageGenericTypeTraits;
  1268. template<typename Type>
  1269. class RepeatedMessageTypeTraits
  1270. {
  1271. public:
  1272. typedef const Type& ConstType;
  1273. typedef Type* MutableType;
  1274. typedef RepeatedMessageTypeTraits<Type> Repeated;
  1275. typedef RepeatedPtrField<Type> RepeatedFieldType;
  1276. static inline ConstType Get(int number, const ExtensionSet& set, int index)
  1277. {
  1278. return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
  1279. }
  1280. static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */, int /* index */)
  1281. {
  1282. // Cannot be implemented because of forward declared messages?
  1283. return nullptr;
  1284. }
  1285. static inline std::nullptr_t GetRepeatedPtr(int /* number */, const ExtensionSet& /* set */)
  1286. {
  1287. // Cannot be implemented because of forward declared messages?
  1288. return nullptr;
  1289. }
  1290. static inline MutableType Mutable(int number, int index, ExtensionSet* set)
  1291. {
  1292. return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
  1293. }
  1294. static inline MutableType Add(int number, FieldType field_type, ExtensionSet* set)
  1295. {
  1296. return static_cast<Type*>(
  1297. set->AddMessage(number, field_type, Type::default_instance(), nullptr)
  1298. );
  1299. }
  1300. static inline const RepeatedPtrField<Type>& GetRepeated(
  1301. int number, const ExtensionSet& set
  1302. )
  1303. {
  1304. // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
  1305. // casting hack applies here, because a RepeatedPtrField<MessageLite>
  1306. // cannot naturally become a RepeatedPtrType<Type> even though Type is
  1307. // presumably a message. google::protobuf::Message goes through similar contortions
  1308. // with a reinterpret_cast<>.
  1309. return *reinterpret_cast<const RepeatedPtrField<Type>*>(
  1310. set.GetRawRepeatedField(number, GetDefaultRepeatedField())
  1311. );
  1312. }
  1313. static inline RepeatedPtrField<Type>* MutableRepeated(int number, FieldType field_type, bool is_packed, ExtensionSet* set)
  1314. {
  1315. return reinterpret_cast<RepeatedPtrField<Type>*>(
  1316. set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)
  1317. );
  1318. }
  1319. static const RepeatedFieldType* GetDefaultRepeatedField();
  1320. template<typename ExtendeeT>
  1321. static void Register(int number, FieldType type, bool is_packed, LazyEagerVerifyFnType fn)
  1322. {
  1323. ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), number, type, true, is_packed, &Type::default_instance(), fn);
  1324. }
  1325. };
  1326. template<typename Type>
  1327. inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
  1328. RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField()
  1329. {
  1330. static auto instance = OnShutdownDelete(new RepeatedFieldType);
  1331. return instance;
  1332. }
  1333. // -------------------------------------------------------------------
  1334. // ExtensionIdentifier
  1335. // This is the type of actual extension objects. E.g. if you have:
  1336. // extend Foo {
  1337. // optional int32 bar = 1234;
  1338. // }
  1339. // then "bar" will be defined in C++ as:
  1340. // ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32_t>, 5, false> bar(1234);
  1341. //
  1342. // Note that we could, in theory, supply the field number as a template
  1343. // parameter, and thus make an instance of ExtensionIdentifier have no
  1344. // actual contents. However, if we did that, then using an extension
  1345. // identifier would not necessarily cause the compiler to output any sort
  1346. // of reference to any symbol defined in the extension's .pb.o file. Some
  1347. // linkers will actually drop object files that are not explicitly referenced,
  1348. // but that would be bad because it would cause this extension to not be
  1349. // registered at static initialization, and therefore using it would crash.
  1350. template<typename ExtendeeType, typename TypeTraitsType, FieldType field_type, bool is_packed>
  1351. class ExtensionIdentifier
  1352. {
  1353. public:
  1354. typedef TypeTraitsType TypeTraits;
  1355. typedef ExtendeeType Extendee;
  1356. ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value, LazyEagerVerifyFnType verify_func = nullptr) :
  1357. number_(number),
  1358. default_value_(default_value)
  1359. {
  1360. Register(number, verify_func);
  1361. }
  1362. inline int number() const
  1363. {
  1364. return number_;
  1365. }
  1366. typename TypeTraits::ConstType default_value() const
  1367. {
  1368. return default_value_;
  1369. }
  1370. static void Register(int number, LazyEagerVerifyFnType verify_func)
  1371. {
  1372. TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed, verify_func);
  1373. }
  1374. typename TypeTraits::ConstType const& default_value_ref() const
  1375. {
  1376. return default_value_;
  1377. }
  1378. private:
  1379. const int number_;
  1380. typename TypeTraits::ConstType default_value_;
  1381. };
  1382. // -------------------------------------------------------------------
  1383. // Generated accessors
  1384. // Used to retrieve a lazy extension, may return nullptr in some environments.
  1385. extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension*
  1386. MaybeCreateLazyExtension(Arena* arena);
  1387. } // namespace internal
  1388. // Call this function to ensure that this extensions's reflection is linked into
  1389. // the binary:
  1390. //
  1391. // google::protobuf::LinkExtensionReflection(Foo::my_extension);
  1392. //
  1393. // This will ensure that the following lookup will succeed:
  1394. //
  1395. // DescriptorPool::generated_pool()->FindExtensionByName("Foo.my_extension");
  1396. //
  1397. // This is often relevant for parsing extensions in text mode.
  1398. //
  1399. // As a side-effect, it will also guarantee that anything else from the same
  1400. // .proto file will also be available for lookup in the generated pool.
  1401. //
  1402. // This function does not actually register the extension, so it does not need
  1403. // to be called before the lookup. However it does need to occur in a function
  1404. // that cannot be stripped from the binary (ie. it must be reachable from main).
  1405. //
  1406. // Best practice is to call this function as close as possible to where the
  1407. // reflection is actually needed. This function is very cheap to call, so you
  1408. // should not need to worry about its runtime overhead except in tight loops (on
  1409. // x86-64 it compiles into two "mov" instructions).
  1410. template<typename ExtendeeType, typename TypeTraitsType, internal::FieldType field_type, bool is_packed>
  1411. void LinkExtensionReflection(
  1412. const google::protobuf::internal::ExtensionIdentifier<
  1413. ExtendeeType,
  1414. TypeTraitsType,
  1415. field_type,
  1416. is_packed>& extension
  1417. )
  1418. {
  1419. internal::StrongReference(extension);
  1420. }
  1421. } // namespace protobuf
  1422. } // namespace google
  1423. #include <google/protobuf/port_undef.inc>
  1424. #endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__