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.

generated_message_reflection.h 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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_GENERATED_MESSAGE_REFLECTION_H__
  37. #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
  38. #include <google/protobuf/stubs/casts.h>
  39. #include <google/protobuf/stubs/common.h>
  40. #include <google/protobuf/stubs/once.h>
  41. #include <google/protobuf/port.h>
  42. #include <google/protobuf/descriptor.h>
  43. #include <google/protobuf/generated_enum_reflection.h>
  44. #include <google/protobuf/unknown_field_set.h>
  45. // Must be included last.
  46. #include <google/protobuf/port_def.inc>
  47. #ifdef SWIG
  48. #error "You cannot SWIG proto headers"
  49. #endif
  50. namespace google
  51. {
  52. namespace protobuf
  53. {
  54. class MapKey;
  55. class MapValueRef;
  56. class MessageLayoutInspector;
  57. class Message;
  58. struct Metadata;
  59. } // namespace protobuf
  60. } // namespace google
  61. namespace google
  62. {
  63. namespace protobuf
  64. {
  65. namespace internal
  66. {
  67. class DefaultEmptyOneof;
  68. // Defined in other files.
  69. class ExtensionSet; // extension_set.h
  70. class WeakFieldMap; // weak_field_map.h
  71. // This struct describes the internal layout of the message, hence this is
  72. // used to act on the message reflectively.
  73. // default_instance: The default instance of the message. This is only
  74. // used to obtain pointers to default instances of embedded
  75. // messages, which GetMessage() will return if the particular
  76. // sub-message has not been initialized yet. (Thus, all
  77. // embedded message fields *must* have non-null pointers
  78. // in the default instance.)
  79. // offsets: An array of ints giving the byte offsets.
  80. // For each oneof or weak field, the offset is relative to the
  81. // default_instance. These can be computed at compile time
  82. // using the
  83. // PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
  84. // macro. For each none oneof field, the offset is related to
  85. // the start of the message object. These can be computed at
  86. // compile time using the
  87. // PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
  88. // Besides offsets for all fields, this array also contains
  89. // offsets for oneof unions. The offset of the i-th oneof union
  90. // is offsets[descriptor->field_count() + i].
  91. // has_bit_indices: Mapping from field indexes to their index in the has
  92. // bit array.
  93. // has_bits_offset: Offset in the message of an array of uint32s of size
  94. // descriptor->field_count()/32, rounded up. This is a
  95. // bitfield where each bit indicates whether or not the
  96. // corresponding field of the message has been initialized.
  97. // The bit for field index i is obtained by the expression:
  98. // has_bits[i / 32] & (1 << (i % 32))
  99. // unknown_fields_offset: Offset in the message of the UnknownFieldSet for
  100. // the message.
  101. // extensions_offset: Offset in the message of the ExtensionSet for the
  102. // message, or -1 if the message type has no extension
  103. // ranges.
  104. // oneof_case_offset: Offset in the message of an array of uint32s of
  105. // size descriptor->oneof_decl_count(). Each uint32_t
  106. // indicates what field is set for each oneof.
  107. // object_size: The size of a message object of this type, as measured
  108. // by sizeof().
  109. // arena_offset: If a message doesn't have a unknown_field_set that stores
  110. // the arena, it must have a direct pointer to the arena.
  111. // weak_field_map_offset: If the message proto has weak fields, this is the
  112. // offset of _weak_field_map_ in the generated proto. Otherwise
  113. // -1.
  114. struct ReflectionSchema
  115. {
  116. public:
  117. // Size of a google::protobuf::Message object of this type.
  118. uint32_t GetObjectSize() const
  119. {
  120. return static_cast<uint32_t>(object_size_);
  121. }
  122. bool InRealOneof(const FieldDescriptor* field) const
  123. {
  124. return field->containing_oneof() &&
  125. !field->containing_oneof()->is_synthetic();
  126. }
  127. // Offset of a non-oneof field. Getting a field offset is slightly more
  128. // efficient when we know statically that it is not a oneof field.
  129. uint32_t GetFieldOffsetNonOneof(const FieldDescriptor* field) const
  130. {
  131. GOOGLE_DCHECK(!InRealOneof(field));
  132. return OffsetValue(offsets_[field->index()], field->type());
  133. }
  134. // Offset of any field.
  135. uint32_t GetFieldOffset(const FieldDescriptor* field) const
  136. {
  137. if (InRealOneof(field))
  138. {
  139. size_t offset =
  140. static_cast<size_t>(field->containing_type()->field_count()) +
  141. field->containing_oneof()->index();
  142. return OffsetValue(offsets_[offset], field->type());
  143. }
  144. else
  145. {
  146. return GetFieldOffsetNonOneof(field);
  147. }
  148. }
  149. bool IsFieldInlined(const FieldDescriptor* field) const
  150. {
  151. return Inlined(offsets_[field->index()], field->type());
  152. }
  153. uint32_t GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const
  154. {
  155. return static_cast<uint32_t>(oneof_case_offset_) +
  156. static_cast<uint32_t>(
  157. static_cast<size_t>(oneof_descriptor->index()) *
  158. sizeof(uint32_t)
  159. );
  160. }
  161. bool HasHasbits() const
  162. {
  163. return has_bits_offset_ != -1;
  164. }
  165. // Bit index within the bit array of hasbits. Bit order is low-to-high.
  166. uint32_t HasBitIndex(const FieldDescriptor* field) const
  167. {
  168. if (has_bits_offset_ == -1)
  169. return static_cast<uint32_t>(-1);
  170. GOOGLE_DCHECK(HasHasbits());
  171. return has_bit_indices_[field->index()];
  172. }
  173. // Byte offset of the hasbits array.
  174. uint32_t HasBitsOffset() const
  175. {
  176. GOOGLE_DCHECK(HasHasbits());
  177. return static_cast<uint32_t>(has_bits_offset_);
  178. }
  179. bool HasInlinedString() const
  180. {
  181. return inlined_string_donated_offset_ != -1;
  182. }
  183. // Bit index within the bit array of _inlined_string_donated_. Bit order is
  184. // low-to-high.
  185. uint32_t InlinedStringIndex(const FieldDescriptor* field) const
  186. {
  187. GOOGLE_DCHECK(HasInlinedString());
  188. return inlined_string_indices_[field->index()];
  189. }
  190. // Byte offset of the _inlined_string_donated_ array.
  191. uint32_t InlinedStringDonatedOffset() const
  192. {
  193. GOOGLE_DCHECK(HasInlinedString());
  194. return static_cast<uint32_t>(inlined_string_donated_offset_);
  195. }
  196. // The offset of the InternalMetadataWithArena member.
  197. // For Lite this will actually be an InternalMetadataWithArenaLite.
  198. // The schema doesn't contain enough information to distinguish between
  199. // these two cases.
  200. uint32_t GetMetadataOffset() const
  201. {
  202. return static_cast<uint32_t>(metadata_offset_);
  203. }
  204. // Whether this message has an ExtensionSet.
  205. bool HasExtensionSet() const
  206. {
  207. return extensions_offset_ != -1;
  208. }
  209. // The offset of the ExtensionSet in this message.
  210. uint32_t GetExtensionSetOffset() const
  211. {
  212. GOOGLE_DCHECK(HasExtensionSet());
  213. return static_cast<uint32_t>(extensions_offset_);
  214. }
  215. // The off set of WeakFieldMap when the message contains weak fields.
  216. // The default is 0 for now.
  217. int GetWeakFieldMapOffset() const
  218. {
  219. return weak_field_map_offset_;
  220. }
  221. bool IsDefaultInstance(const Message& message) const
  222. {
  223. return &message == default_instance_;
  224. }
  225. // Returns a pointer to the default value for this field. The size and type
  226. // of the underlying data depends on the field's type.
  227. const void* GetFieldDefault(const FieldDescriptor* field) const
  228. {
  229. return reinterpret_cast<const uint8_t*>(default_instance_) +
  230. OffsetValue(offsets_[field->index()], field->type());
  231. }
  232. // Returns true if the field is implicitly backed by LazyField.
  233. bool IsEagerlyVerifiedLazyField(const FieldDescriptor* field) const
  234. {
  235. GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
  236. (void)field;
  237. return false;
  238. }
  239. bool IsFieldStripped(const FieldDescriptor* field) const
  240. {
  241. (void)field;
  242. return false;
  243. }
  244. bool IsMessageStripped(const Descriptor* descriptor) const
  245. {
  246. (void)descriptor;
  247. return false;
  248. }
  249. bool HasWeakFields() const
  250. {
  251. return weak_field_map_offset_ > 0;
  252. }
  253. // These members are intended to be private, but we cannot actually make them
  254. // private because this prevents us from using aggregate initialization of
  255. // them, ie.
  256. //
  257. // ReflectionSchema schema = {a, b, c, d, e, ...};
  258. // private:
  259. const Message* default_instance_;
  260. const uint32_t* offsets_;
  261. const uint32_t* has_bit_indices_;
  262. int has_bits_offset_;
  263. int metadata_offset_;
  264. int extensions_offset_;
  265. int oneof_case_offset_;
  266. int object_size_;
  267. int weak_field_map_offset_;
  268. const uint32_t* inlined_string_indices_;
  269. int inlined_string_donated_offset_;
  270. // We tag offset values to provide additional data about fields (such as
  271. // "unused" or "lazy" or "inlined").
  272. static uint32_t OffsetValue(uint32_t v, FieldDescriptor::Type type)
  273. {
  274. if (type == FieldDescriptor::TYPE_MESSAGE ||
  275. type == FieldDescriptor::TYPE_STRING ||
  276. type == FieldDescriptor::TYPE_BYTES)
  277. {
  278. return v & 0xFFFFFFFEu;
  279. }
  280. return v;
  281. }
  282. static bool Inlined(uint32_t v, FieldDescriptor::Type type)
  283. {
  284. if (type == FieldDescriptor::TYPE_STRING ||
  285. type == FieldDescriptor::TYPE_BYTES)
  286. {
  287. return (v & 1u) != 0u;
  288. }
  289. else
  290. {
  291. // Non string/byte fields are not inlined.
  292. return false;
  293. }
  294. }
  295. };
  296. // Structs that the code generator emits directly to describe a message.
  297. // These should never used directly except to build a ReflectionSchema
  298. // object.
  299. //
  300. // EXPERIMENTAL: these are changing rapidly, and may completely disappear
  301. // or merge with ReflectionSchema.
  302. struct MigrationSchema
  303. {
  304. int32_t offsets_index;
  305. int32_t has_bit_indices_index;
  306. int32_t inlined_string_indices_index;
  307. int object_size;
  308. };
  309. // This struct tries to reduce unnecessary padding.
  310. // The num_xxx might not be close to their respective pointer, but this saves
  311. // padding.
  312. struct PROTOBUF_EXPORT DescriptorTable
  313. {
  314. mutable bool is_initialized;
  315. bool is_eager;
  316. int size; // of serialized descriptor
  317. const char* descriptor;
  318. const char* filename;
  319. once_flag* once;
  320. const DescriptorTable* const* deps;
  321. int num_deps;
  322. int num_messages;
  323. const MigrationSchema* schemas;
  324. const Message* const* default_instances;
  325. const uint32_t* offsets;
  326. // update the following descriptor arrays.
  327. Metadata* file_level_metadata;
  328. const EnumDescriptor** file_level_enum_descriptors;
  329. const ServiceDescriptor** file_level_service_descriptors;
  330. };
  331. enum
  332. {
  333. // Tag used on offsets for fields that don't have a real offset.
  334. // For example, weak message fields go into the WeakFieldMap and not in an
  335. // actual field.
  336. kInvalidFieldOffsetTag = 0x40000000u,
  337. };
  338. // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
  339. // and uses it to populate all of the global variables which store pointers to
  340. // the descriptor objects. It also constructs the reflection objects. It is
  341. // called the first time anyone calls descriptor() or GetReflection() on one of
  342. // the types defined in the file. AssignDescriptors() is thread-safe.
  343. void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table, bool eager = false);
  344. // Overload used to implement GetMetadataStatic in the generated code.
  345. // See comments in compiler/cpp/internal/file.cc as to why.
  346. // It takes a `Metadata` and returns it to allow for tail calls and reduce
  347. // binary size.
  348. Metadata PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* (*table)(), internal::once_flag* once, const Metadata& metadata);
  349. // These cannot be in lite so we put them in the reflection.
  350. PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base, uint32_t offset, uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output);
  351. struct PROTOBUF_EXPORT AddDescriptorsRunner
  352. {
  353. explicit AddDescriptorsRunner(const DescriptorTable* table);
  354. };
  355. } // namespace internal
  356. } // namespace protobuf
  357. } // namespace google
  358. #include <google/protobuf/port_undef.inc>
  359. #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__