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 14 kB

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