generated_message_reflection.h 14 KB

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