Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-23 09:12:51

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // This header is logically internal, but is made public because it is used
0013 // from protocol-compiler-generated code, which may reside in other components.
0014 
0015 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
0016 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
0017 
0018 #include <atomic>
0019 #include <cstddef>
0020 #include <cstdint>
0021 #include <string>
0022 
0023 #include "absl/base/call_once.h"
0024 #include "absl/base/optimization.h"
0025 #include "absl/log/absl_check.h"
0026 #include "google/protobuf/descriptor.h"
0027 #include "google/protobuf/generated_enum_reflection.h"
0028 #include "google/protobuf/unknown_field_set.h"
0029 
0030 // Must be included last.
0031 #include "google/protobuf/port_def.inc"
0032 
0033 #ifdef SWIG
0034 #error "You cannot SWIG proto headers"
0035 #endif
0036 
0037 namespace google {
0038 namespace protobuf {
0039 class MapKey;
0040 class MapValueRef;
0041 class MessageLayoutInspector;
0042 class Message;
0043 struct Metadata;
0044 
0045 namespace io {
0046 class CodedOutputStream;
0047 }
0048 }  // namespace protobuf
0049 }  // namespace google
0050 
0051 namespace google {
0052 namespace protobuf {
0053 namespace internal {
0054 class DefaultEmptyOneof;
0055 // Defined in other files.
0056 class ExtensionSet;  // extension_set.h
0057 class WeakFieldMap;  // weak_field_map.h
0058 
0059 // Tag used on offsets for fields that don't have a real offset.
0060 // For example, weak message fields go into the WeakFieldMap and not in an
0061 // actual field.
0062 inline constexpr uint32_t kInvalidFieldOffsetTag = 0x40000000u;
0063 
0064 // Mask used on offsets for split fields.
0065 inline constexpr uint32_t kSplitFieldOffsetMask = 0x80000000u;
0066 inline constexpr uint32_t kLazyMask = 0x1u;
0067 inline constexpr uint32_t kInlinedMask = 0x1u;
0068 inline constexpr uint32_t kMicroStringMask = 0x2u;
0069 
0070 // This struct describes the internal layout of the message, hence this is
0071 // used to act on the message reflectively.
0072 //   default_instance:  The default instance of the message.  This is only
0073 //                  used to obtain pointers to default instances of embedded
0074 //                  messages, which GetMessage() will return if the particular
0075 //                  sub-message has not been initialized yet.  (Thus, all
0076 //                  embedded message fields *must* have non-null pointers
0077 //                  in the default instance.)
0078 //   offsets:       An array of ints giving the byte offsets.
0079 //                  For each oneof or weak field, the offset is relative to the
0080 //                  default_instance. These can be computed at compile time
0081 //                  using the
0082 //                  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
0083 //                  macro. For each none oneof field, the offset is related to
0084 //                  the start of the message object.  These can be computed at
0085 //                  compile time using the
0086 //                  PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
0087 //                  Besides offsets for all fields, this array also contains
0088 //                  offsets for oneof unions. The offset of the i-th oneof union
0089 //                  is offsets[descriptor->field_count() + i].
0090 //   has_bit_indices:  Mapping from field indexes to their index in the has
0091 //                  bit array.
0092 //   has_bits_offset:  Offset in the message of an array of uint32s of size
0093 //                  descriptor->field_count()/32, rounded up.  This is a
0094 //                  bitfield where each bit indicates whether or not the
0095 //                  corresponding field of the message has been initialized.
0096 //                  The bit for field index i is obtained by the expression:
0097 //                    has_bits[i / 32] & (1 << (i % 32))
0098 //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
0099 //                  the message.
0100 //   extensions_offset:  Offset in the message of the ExtensionSet for the
0101 //                  message, or -1 if the message type has no extension
0102 //                  ranges.
0103 //   oneof_case_offset:  Offset in the message of an array of uint32s of
0104 //                  size descriptor->oneof_decl_count().  Each uint32_t
0105 //                  indicates what field is set for each oneof.
0106 //   object_size:   The size of a message object of this type, as measured
0107 //                  by sizeof().
0108 //   arena_offset:  If a message doesn't have a unknown_field_set that stores
0109 //                  the arena, it must have a direct pointer to the arena.
0110 //   weak_field_map_offset: If the message proto has weak fields, this is the
0111 //                  offset of _weak_field_map_ in the generated proto. Otherwise
0112 //                  -1.
0113 struct ReflectionSchema {
0114  public:
0115   // Size of a google::protobuf::Message object of this type.
0116   uint32_t GetObjectSize() const { return static_cast<uint32_t>(object_size_); }
0117 
0118   bool InRealOneof(const FieldDescriptor* field) const {
0119     return field->real_containing_oneof();
0120   }
0121 
0122   // Offset of any field.
0123   template <typename Type = void>
0124   uint32_t GetFieldOffset(const FieldDescriptor* field) const {
0125     return OffsetValue<Type>(offsets_[field->index()], field->type());
0126   }
0127 
0128   bool IsFieldInlined(const FieldDescriptor* field) const {
0129     return Inlined(offsets_[field->index()], field->type());
0130   }
0131 
0132   bool IsFieldMicroString(const FieldDescriptor* field) const {
0133     return IsMicroString(offsets_[field->index()], field->type());
0134   }
0135 
0136   uint32_t GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
0137     return static_cast<uint32_t>(oneof_case_offset_) +
0138            static_cast<uint32_t>(
0139                static_cast<size_t>(oneof_descriptor->index()) *
0140                sizeof(uint32_t));
0141   }
0142 
0143   // Returns true iff the field object has usable hasbit offset.
0144   // Note that this is not necessarily correlated with *field presence* :
0145   // Fields with implicit presence (i.e. ones that don't expose has_foo API)
0146   // can still have hasbits in their underlying implementation.
0147   bool HasHasbits() const { return has_bits_offset_ != -1; }
0148 
0149   // Bit index within the bit array of hasbits.  Bit order is low-to-high.
0150   uint32_t HasBitIndex(const FieldDescriptor* field) const {
0151     ABSL_DCHECK(!field->is_extension());
0152     if (has_bits_offset_ == -1) return static_cast<uint32_t>(-1);
0153     ABSL_DCHECK(HasHasbits());
0154     return has_bit_indices_[field->index()];
0155   }
0156 
0157   // Byte offset of the hasbits array.
0158   uint32_t HasBitsOffset() const {
0159     ABSL_DCHECK(HasHasbits());
0160     return static_cast<uint32_t>(has_bits_offset_);
0161   }
0162 
0163   bool HasInlinedString() const { return inlined_string_donated_offset_ != -1; }
0164 
0165   // Bit index within the bit array of _inlined_string_donated_.  Bit order is
0166   // low-to-high.
0167   uint32_t InlinedStringIndex(const FieldDescriptor* field) const {
0168     ABSL_DCHECK(HasInlinedString());
0169     return inlined_string_indices_[field->index()];
0170   }
0171 
0172   // Byte offset of the _inlined_string_donated_ array.
0173   uint32_t InlinedStringDonatedOffset() const {
0174     ABSL_DCHECK(HasInlinedString());
0175     return static_cast<uint32_t>(inlined_string_donated_offset_);
0176   }
0177 
0178   // Whether this message has an ExtensionSet.
0179   bool HasExtensionSet() const { return extensions_offset_ != -1; }
0180 
0181   // The offset of the ExtensionSet in this message.
0182   uint32_t GetExtensionSetOffset() const {
0183     ABSL_DCHECK(HasExtensionSet());
0184     return static_cast<uint32_t>(extensions_offset_);
0185   }
0186 
0187   // The off set of WeakFieldMap when the message contains weak fields.
0188   // The default is 0 for now.
0189   int GetWeakFieldMapOffset() const { return weak_field_map_offset_; }
0190 
0191   bool IsDefaultInstance(const Message& message) const {
0192     return &message == default_instance_;
0193   }
0194 
0195   // Returns a pointer to the default value for this field.  The size and type
0196   // of the underlying data depends on the field's type.
0197   const void* GetFieldDefault(const FieldDescriptor* field) const {
0198     return reinterpret_cast<const uint8_t*>(default_instance_) +
0199            OffsetValue<void>(offsets_[field->index()], field->type());
0200   }
0201 
0202   // Returns true if the field is implicitly backed by LazyField.
0203   bool IsEagerlyVerifiedLazyField(const FieldDescriptor* field) const {
0204     ABSL_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
0205     (void)field;
0206     return false;
0207   }
0208 
0209   bool IsSplit() const { return split_offset_ != -1; }
0210 
0211   bool IsSplit(const FieldDescriptor* field) const {
0212     return split_offset_ != -1 &&
0213            (offsets_[field->index()] & kSplitFieldOffsetMask) != 0;
0214   }
0215 
0216   // Byte offset of _split_.
0217   uint32_t SplitOffset() const {
0218     ABSL_DCHECK(IsSplit());
0219     return static_cast<uint32_t>(split_offset_);
0220   }
0221 
0222   uint32_t SizeofSplit() const {
0223     ABSL_DCHECK(IsSplit());
0224     return static_cast<uint32_t>(sizeof_split_);
0225   }
0226 
0227 
0228   bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
0229 
0230   // These members are intended to be private, but we cannot actually make them
0231   // private because this prevents us from using aggregate initialization of
0232   // them, ie.
0233   //
0234   //   ReflectionSchema schema = {a, b, c, d, e, ...};
0235   // private:
0236   const Message* default_instance_;
0237   const uint32_t* offsets_;
0238   const uint32_t* has_bit_indices_;
0239   int has_bits_offset_;
0240   int extensions_offset_;
0241   int oneof_case_offset_;
0242   int object_size_;
0243   int weak_field_map_offset_;
0244   const uint32_t* inlined_string_indices_;
0245   int inlined_string_donated_offset_;
0246   int split_offset_;
0247   int sizeof_split_;
0248 
0249   // We tag offset values to provide additional data about fields (such as
0250   // "unused" or "lazy" or "inlined").
0251   template <typename Type>
0252   static uint32_t OffsetValue(uint32_t v, FieldDescriptor::Type type) {
0253     if constexpr (!std::is_void_v<Type>) {
0254       // If the type is passed, statically use the alignment for the mask.
0255       // Faster than checking `type`.
0256       return v & ~kSplitFieldOffsetMask & ~(alignof(Type) - 1);
0257     }
0258     if (type == FieldDescriptor::TYPE_MESSAGE ||
0259         type == FieldDescriptor::TYPE_STRING ||
0260         type == FieldDescriptor::TYPE_BYTES) {
0261       return v & ~kSplitFieldOffsetMask & ~kInlinedMask & ~kLazyMask &
0262              ~kMicroStringMask;
0263     }
0264     return v & (~kSplitFieldOffsetMask);
0265   }
0266 
0267   static bool Inlined(uint32_t v, FieldDescriptor::Type type) {
0268     if (type == FieldDescriptor::TYPE_STRING ||
0269         type == FieldDescriptor::TYPE_BYTES) {
0270       return (v & kInlinedMask) != 0u;
0271     } else {
0272       // Non string/byte fields are not inlined.
0273       return false;
0274     }
0275   }
0276 
0277   static bool IsMicroString(uint32_t v, FieldDescriptor::Type type) {
0278     ABSL_DCHECK(type == FieldDescriptor::TYPE_STRING ||
0279                 type == FieldDescriptor::TYPE_BYTES)
0280         << type;
0281     return (v & kMicroStringMask) != 0u;
0282   }
0283 };
0284 
0285 // Structs that the code generator emits directly to describe a message.
0286 // These should never used directly except to build a ReflectionSchema
0287 // object.
0288 //
0289 // EXPERIMENTAL: these are changing rapidly, and may completely disappear
0290 // or merge with ReflectionSchema.
0291 struct MigrationSchema {
0292   int32_t offsets_index;
0293   int object_size;
0294 };
0295 
0296 // This struct tries to reduce unnecessary padding.
0297 // The num_xxx might not be close to their respective pointer, but this saves
0298 // padding.
0299 struct PROTOBUF_EXPORT DescriptorTable {
0300   mutable bool is_initialized;
0301   bool is_eager;
0302   int size;  // of serialized descriptor
0303   const char* descriptor;
0304   const char* filename;
0305   absl::once_flag* once;
0306   const DescriptorTable* const* deps;
0307   int num_deps;
0308   int num_messages;
0309   const MigrationSchema* schemas;
0310   const Message* const* default_instances;
0311   const uint32_t* offsets;
0312   // update the following descriptor arrays.
0313   const EnumDescriptor** file_level_enum_descriptors;
0314   const ServiceDescriptor** file_level_service_descriptors;
0315 };
0316 
0317 // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
0318 // and uses it to populate all of the global variables which store pointers to
0319 // the descriptor objects.  It also constructs the reflection objects.  It is
0320 // called the first time anyone calls descriptor() or GetReflection() on one of
0321 // the types defined in the file.  AssignDescriptors() is thread-safe.
0322 void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table);
0323 // As above, but the caller did the call_once call already.
0324 void PROTOBUF_EXPORT
0325 AssignDescriptorsOnceInnerCall(const DescriptorTable* table);
0326 
0327 // These cannot be in lite so we put them in the reflection.
0328 PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base,
0329                                                uint32_t offset, uint32_t tag,
0330                                                uint32_t has_offset,
0331                                                io::CodedOutputStream* output);
0332 
0333 PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstances();
0334 
0335 PROTOBUF_EXPORT void AddDescriptors(const DescriptorTable* table);
0336 
0337 struct PROTOBUF_EXPORT AddDescriptorsRunner {
0338   explicit AddDescriptorsRunner(const DescriptorTable* table);
0339 };
0340 
0341 // Retrieves the existing prototype out of a descriptor table.
0342 // If it doesn't exist:
0343 //  - If force_build is true, asks the generated message factory for one.
0344 //  - Otherwise, return null
0345 const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table,
0346                                              int index, bool force_build);
0347 
0348 struct DenseEnumCacheInfo {
0349   std::atomic<const std::string**> cache;
0350   int min_val;
0351   int max_val;
0352   const EnumDescriptor* (*descriptor_fn)();
0353 };
0354 PROTOBUF_EXPORT const std::string& NameOfDenseEnumSlow(int v,
0355                                                        DenseEnumCacheInfo*);
0356 
0357 // Similar to the routine NameOfEnum, this routine returns the name of an enum.
0358 // Unlike that routine, it allocates, on-demand, a block of pointers to the
0359 // std::string objects allocated by reflection to store the enum names. This
0360 // way, as long as the enum values are fairly dense, looking them up can be
0361 // very fast. This assumes all the enums fall in the range [min_val .. max_val].
0362 template <const EnumDescriptor* (*descriptor_fn)(), int min_val, int max_val>
0363 const std::string& NameOfDenseEnum(int v) {
0364   static_assert(max_val - min_val >= 0, "Too many enums between min and max.");
0365   static DenseEnumCacheInfo deci = {/* atomic ptr */ {}, min_val, max_val,
0366                                     descriptor_fn};
0367   const std::string** cache = deci.cache.load(std::memory_order_acquire );
0368   if (ABSL_PREDICT_TRUE(cache != nullptr)) {
0369     if (ABSL_PREDICT_TRUE(v >= min_val && v <= max_val)) {
0370       return *cache[v - min_val];
0371     }
0372   }
0373   return NameOfDenseEnumSlow(v, &deci);
0374 }
0375 
0376 // Returns whether this type of field is stored in the split struct as a raw
0377 // pointer.
0378 PROTOBUF_EXPORT bool SplitFieldHasExtraIndirection(
0379     const FieldDescriptor* field);
0380 
0381 }  // namespace internal
0382 }  // namespace protobuf
0383 }  // namespace google
0384 
0385 #include "google/protobuf/port_undef.inc"
0386 
0387 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__