Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:21

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 #ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
0009 #define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
0010 
0011 #include <string>
0012 #include <utility>
0013 
0014 #include "absl/log/absl_check.h"
0015 #include "absl/strings/string_view.h"
0016 #include "google/protobuf/arenastring.h"
0017 #include "google/protobuf/explicitly_constructed.h"
0018 #include "google/protobuf/message_lite.h"
0019 #include "google/protobuf/port.h"
0020 
0021 // Must be included last.
0022 #include "google/protobuf/port_def.inc"
0023 
0024 #ifdef SWIG
0025 #error "You cannot SWIG proto headers"
0026 #endif
0027 
0028 namespace google {
0029 namespace protobuf {
0030 
0031 class Arena;
0032 
0033 namespace internal {
0034 
0035 // InlinedStringField wraps a std::string instance and exposes an API similar to
0036 // ArenaStringPtr's wrapping of a std::string* instance.
0037 //
0038 // default_value parameters are taken for consistency with ArenaStringPtr, but
0039 // are not used for most methods. With inlining, these should be removed from
0040 // the generated binary.
0041 //
0042 // InlinedStringField has a donating mechanism that allows string buffer
0043 // allocated on arena. A string is donated means both the string container and
0044 // the data buffer are on arena. The donating mechanism here is similar to the
0045 // one in ArenaStringPtr with some differences:
0046 //
0047 // When an InlinedStringField is constructed, the donating state is true. This
0048 // is because the string container is directly stored in the message on the
0049 // arena:
0050 //
0051 //   Construction: donated=true
0052 //   Arena:
0053 //   +-----------------------+
0054 //   |Message foo:           |
0055 //   | +-------------------+ |
0056 //   | |InlinedStringField:| |
0057 //   | | +-----+           | |
0058 //   | | | | | |           | |
0059 //   | | +-----+           | |
0060 //   | +-------------------+ |
0061 //   +-----------------------+
0062 //
0063 // When lvalue Set is called, the donating state is still true. String data will
0064 // be allocated on the arena:
0065 //
0066 //   Lvalue Set: donated=true
0067 //   Arena:
0068 //   +-----------------------+
0069 //   |Message foo:           |
0070 //   | +-------------------+ |
0071 //   | |InlinedStringField:| |
0072 //   | | +-----+           | |
0073 //   | | | | | |           | |
0074 //   | | +|----+           | |
0075 //   | +--|----------------+ |
0076 //   |    V                  |
0077 //   |  +----------------+   |
0078 //   |  |'f','o','o',... |   |
0079 //   |  +----------------+   |
0080 //   +-----------------------+
0081 //
0082 // Some operations will undonate a donated string, including: Mutable,
0083 // SetAllocated, Rvalue Set, and Swap with a non-donated string.
0084 //
0085 // For more details of the donating states transitions, go/pd-inlined-string.
0086 class PROTOBUF_EXPORT InlinedStringField {
0087  public:
0088   InlinedStringField() { Init(); }
0089   InlinedStringField(const InlinedStringField&) = delete;
0090   InlinedStringField& operator=(const InlinedStringField&) = delete;
0091   inline void Init() { new (get_mutable()) std::string(); }
0092   // Add the dummy parameter just to make InlinedStringField(nullptr)
0093   // unambiguous.
0094   constexpr InlinedStringField(
0095       const ExplicitlyConstructed<std::string>* /*default_value*/,
0096       bool /*dummy*/)
0097       : value_{} {}
0098   explicit InlinedStringField(const std::string& default_value);
0099   explicit InlinedStringField(Arena* arena);
0100   InlinedStringField(Arena* arena, const InlinedStringField& rhs);
0101   ~InlinedStringField() { Destruct(); }
0102 
0103   // Lvalue Set. To save space, we pack the donating states of multiple
0104   // InlinedStringFields into an uint32_t `donating_states`. The `mask`
0105   // indicates the position of the bit for this InlinedStringField. `donated` is
0106   // whether this field is donated.
0107   //
0108   // The caller should guarantee that:
0109   //
0110   //   `donated == ((donating_states & ~mask) != 0)`
0111   //
0112   // This method never changes the `donating_states`.
0113   void Set(absl::string_view value, Arena* arena, bool donated,
0114            uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0115 
0116   // Rvalue Set. If this field is donated, this method will undonate this field
0117   // by mutating the `donating_states` according to `mask`.
0118   void Set(std::string&& value, Arena* arena, bool donated,
0119            uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0120 
0121   void Set(const char* str, ::google::protobuf::Arena* arena, bool donated,
0122            uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0123 
0124   void Set(const char* str, size_t size, ::google::protobuf::Arena* arena, bool donated,
0125            uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0126 
0127   template <typename RefWrappedType>
0128   void Set(std::reference_wrapper<RefWrappedType> const_string_ref,
0129            ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0130            uint32_t mask, MessageLite* msg);
0131 
0132   void SetBytes(absl::string_view value, Arena* arena, bool donated,
0133                 uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0134 
0135   void SetBytes(std::string&& value, Arena* arena, bool donated,
0136                 uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0137 
0138   void SetBytes(const char* str, ::google::protobuf::Arena* arena, bool donated,
0139                 uint32_t* donating_states, uint32_t mask, MessageLite* msg);
0140 
0141   void SetBytes(const void* p, size_t size, ::google::protobuf::Arena* arena,
0142                 bool donated, uint32_t* donating_states, uint32_t mask,
0143                 MessageLite* msg);
0144 
0145   template <typename RefWrappedType>
0146   void SetBytes(std::reference_wrapper<RefWrappedType> const_string_ref,
0147                 ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0148                 uint32_t mask, MessageLite* msg);
0149 
0150   PROTOBUF_NDEBUG_INLINE void SetNoArena(absl::string_view value);
0151   PROTOBUF_NDEBUG_INLINE void SetNoArena(std::string&& value);
0152 
0153   // Basic accessors.
0154   PROTOBUF_NDEBUG_INLINE const std::string& Get() const { return GetNoArena(); }
0155   PROTOBUF_NDEBUG_INLINE const std::string& GetNoArena() const;
0156 
0157   // Mutable returns a std::string* instance that is heap-allocated. If this
0158   // field is donated, this method undonates this field by mutating the
0159   // `donating_states` according to `mask`, and copies the content of the
0160   // original string to the returning string.
0161   std::string* Mutable(Arena* arena, bool donated, uint32_t* donating_states,
0162                        uint32_t mask, MessageLite* msg);
0163   std::string* Mutable(const LazyString& default_value, Arena* arena,
0164                        bool donated, uint32_t* donating_states, uint32_t mask,
0165                        MessageLite* msg);
0166 
0167   // Mutable(nullptr_t) is an overload to explicitly support Mutable(nullptr)
0168   // calls used by the internal parser logic. This provides API equivalence with
0169   // ArenaStringPtr, while still protecting against calls with arena pointers.
0170   std::string* Mutable(std::nullptr_t);
0171   std::string* MutableNoCopy(std::nullptr_t);
0172 
0173   // Takes a std::string that is heap-allocated, and takes ownership. The
0174   // std::string's destructor is registered with the arena. Used to implement
0175   // set_allocated_<field> in generated classes.
0176   //
0177   // If this field is donated, this method undonates this field by mutating the
0178   // `donating_states` according to `mask`.
0179   void SetAllocated(const std::string* default_value, std::string* value,
0180                     Arena* arena, bool donated, uint32_t* donating_states,
0181                     uint32_t mask, MessageLite* msg);
0182 
0183   void SetAllocatedNoArena(const std::string* default_value,
0184                            std::string* value);
0185 
0186   // Release returns a std::string* instance that is heap-allocated and is not
0187   // Own()'d by any arena. If the field is not set, this returns nullptr. The
0188   // caller retains ownership. Clears this field back to nullptr state. Used to
0189   // implement release_<field>() methods on generated classes.
0190   PROTOBUF_NODISCARD std::string* Release(Arena* arena, bool donated);
0191   PROTOBUF_NODISCARD std::string* Release();
0192 
0193   // --------------------------------------------------------
0194   // Below functions will be removed in subsequent code change
0195   // --------------------------------------------------------
0196 #ifdef DEPRECATED_METHODS_TO_BE_DELETED
0197   PROTOBUF_NODISCARD std::string* Release(const std::string*, Arena* arena,
0198                                           bool donated) {
0199     return Release(arena, donated);
0200   }
0201 
0202   PROTOBUF_NODISCARD std::string* ReleaseNonDefault(const std::string*,
0203                                                     Arena* arena) {
0204     return Release();
0205   }
0206 
0207   std::string* ReleaseNonDefaultNoArena(const std::string* default_value) {
0208     return Release();
0209   }
0210 
0211   void Set(const std::string*, absl::string_view value, Arena* arena,
0212            bool donated, uint32_t* donating_states, uint32_t mask,
0213            MessageLite* msg) {
0214     Set(value, arena, donated, donating_states, mask, msg);
0215   }
0216 
0217   void Set(const std::string*, std::string&& value, Arena* arena, bool donated,
0218            uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
0219     Set(std::move(value), arena, donated, donating_states, mask, msg);
0220   }
0221 
0222 
0223   template <typename FirstParam>
0224   void Set(FirstParam, const char* str, ::google::protobuf::Arena* arena, bool donated,
0225            uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
0226     Set(str, arena, donated, donating_states, mask, msg);
0227   }
0228 
0229   template <typename FirstParam>
0230   void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena,
0231            bool donated, uint32_t* donating_states, uint32_t mask,
0232            MessageLite* msg) {
0233     Set(str, size, arena, donated, donating_states, mask, msg);
0234   }
0235 
0236   template <typename FirstParam, typename RefWrappedType>
0237   void Set(FirstParam p1,
0238            std::reference_wrapper<RefWrappedType> const_string_ref,
0239            ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0240            uint32_t mask, MessageLite* msg) {
0241     Set(const_string_ref, arena, donated, donating_states, mask, msg);
0242   }
0243 
0244   void SetBytes(const std::string*, absl::string_view value, Arena* arena,
0245                 bool donated, uint32_t* donating_states, uint32_t mask,
0246                 MessageLite* msg) {
0247     Set(value, arena, donated, donating_states, mask, msg);
0248   }
0249 
0250 
0251   void SetBytes(const std::string*, std::string&& value, Arena* arena,
0252                 bool donated, uint32_t* donating_states, uint32_t mask,
0253                 MessageLite* msg) {
0254     Set(std::move(value), arena, donated, donating_states, mask, msg);
0255   }
0256 
0257   template <typename FirstParam>
0258   void SetBytes(FirstParam p1, const char* str, ::google::protobuf::Arena* arena,
0259                 bool donated, uint32_t* donating_states, uint32_t mask,
0260                 MessageLite* msg) {
0261     SetBytes(str, arena, donated, donating_states, mask, msg);
0262   }
0263 
0264   template <typename FirstParam>
0265   void SetBytes(FirstParam p1, const void* p, size_t size,
0266                 ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0267                 uint32_t mask, MessageLite* msg) {
0268     SetBytes(p, size, arena, donated, donating_states, mask, msg);
0269   }
0270 
0271   template <typename FirstParam, typename RefWrappedType>
0272   void SetBytes(FirstParam p1,
0273                 std::reference_wrapper<RefWrappedType> const_string_ref,
0274                 ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0275                 uint32_t mask, MessageLite* msg) {
0276     SetBytes(const_string_ref.get(), arena, donated, donating_states, mask,
0277              msg);
0278   }
0279 
0280   void SetNoArena(const std::string*, absl::string_view value) {
0281     SetNoArena(value);
0282   }
0283   void SetNoArena(const std::string*, std::string&& value) {
0284     SetNoArena(std::move(value));
0285   }
0286 
0287   std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated,
0288                        uint32_t* donating_states, uint32_t mask,
0289                        MessageLite* msg) {
0290     return Mutable(arena, donated, donating_states, mask, msg);
0291   }
0292 
0293   PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault(
0294       const std::string* /*default_value*/) {
0295     return MutableNoCopy(nullptr);
0296   }
0297 
0298 #endif  // DEPRECATED_METHODS_TO_BE_DELETED
0299 
0300   // Arena-safety semantics: this is guarded by the logic in
0301   // Swap()/UnsafeArenaSwap() at the message level, so this method is
0302   // 'unsafe' if called directly.
0303   inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(
0304       InlinedStringField* lhs, bool lhs_arena_dtor_registered,
0305       MessageLite* lhs_msg,  //
0306       InlinedStringField* rhs, bool rhs_arena_dtor_registered,
0307       MessageLite* rhs_msg, Arena* arena);
0308 
0309   // Frees storage (if not on an arena).
0310   PROTOBUF_NDEBUG_INLINE void Destroy(const std::string* default_value,
0311                                       Arena* arena) {
0312     if (arena == nullptr) {
0313       DestroyNoArena(default_value);
0314     }
0315   }
0316   PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const std::string* default_value);
0317 
0318   // Clears content, but keeps allocated std::string, to avoid the overhead of
0319   // heap operations. After this returns, the content (as seen by the user) will
0320   // always be the empty std::string.
0321   PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); }
0322   PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() {
0323     get_mutable()->clear();
0324   }
0325 
0326   // Clears content, but keeps allocated std::string if arena != nullptr, to
0327   // avoid the overhead of heap operations. After this returns, the content (as
0328   // seen by the user) will always be equal to |default_value|.
0329   void ClearToDefault(const LazyString& default_value, Arena* arena,
0330                       bool donated);
0331 
0332   // Generated code / reflection only! Returns a mutable pointer to the string.
0333   PROTOBUF_NDEBUG_INLINE std::string* UnsafeMutablePointer();
0334 
0335   // InlinedStringField doesn't have things like the `default_value` pointer in
0336   // ArenaStringPtr.
0337   static constexpr bool IsDefault() { return false; }
0338   static constexpr bool IsDefault(const std::string*) { return false; }
0339 
0340  private:
0341   // ScopedCheckInvariants checks all string in-variants at destruction.
0342   class ScopedCheckInvariants;
0343 
0344   void Destruct() { get_mutable()->~basic_string(); }
0345 
0346   PROTOBUF_NDEBUG_INLINE std::string* get_mutable();
0347   PROTOBUF_NDEBUG_INLINE const std::string* get_const() const;
0348 
0349   alignas(std::string) char value_[sizeof(std::string)];
0350 
0351   std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated,
0352                            uint32_t* donating_states, uint32_t mask,
0353                            MessageLite* msg);
0354 
0355 
0356   // When constructed in an Arena, we want our destructor to be skipped.
0357   friend class ::google::protobuf::Arena;
0358   typedef void InternalArenaConstructable_;
0359   typedef void DestructorSkippable_;
0360 };
0361 
0362 inline std::string* InlinedStringField::get_mutable() {
0363   return reinterpret_cast<std::string*>(&value_);
0364 }
0365 
0366 inline const std::string* InlinedStringField::get_const() const {
0367   return reinterpret_cast<const std::string*>(&value_);
0368 }
0369 
0370 inline InlinedStringField::InlinedStringField(
0371     const std::string& default_value) {
0372   new (get_mutable()) std::string(default_value);
0373 }
0374 
0375 
0376 #ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
0377 constexpr uint32_t InitDonatingStates() { return ~0u; }
0378 inline void InternalRegisterArenaDtor(Arena*, void*, void (*)(void*)) {}
0379 #else   // !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
0380 constexpr uint32_t InitDonatingStates() { return 0u; }
0381 inline void InternalRegisterArenaDtor(Arena* arena, void* object,
0382                                       void (*destruct)(void*)) {
0383   if (arena != nullptr) {
0384     arena->OwnCustomDestructor(object, destruct);
0385   }
0386 }
0387 #endif  // GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
0388 
0389 inline InlinedStringField::InlinedStringField(Arena* /*arena*/) { Init(); }
0390 
0391 inline InlinedStringField::InlinedStringField(Arena* arena,
0392                                               const InlinedStringField& rhs) {
0393   const std::string& src = *rhs.get_const();
0394   new (value_) std::string(src);
0395 }
0396 
0397 inline const std::string& InlinedStringField::GetNoArena() const {
0398   return *get_const();
0399 }
0400 
0401 inline void InlinedStringField::SetAllocatedNoArena(
0402     const std::string* /*default_value*/, std::string* value) {
0403   if (value == nullptr) {
0404     // Currently, inlined string field can't have non empty default.
0405     get_mutable()->clear();
0406   } else {
0407     get_mutable()->assign(std::move(*value));
0408     delete value;
0409   }
0410 }
0411 
0412 inline void InlinedStringField::DestroyNoArena(const std::string*) {
0413   // This is invoked from the generated message's ArenaDtor, which is used to
0414   // clean up objects not allocated on the Arena.
0415   this->~InlinedStringField();
0416 }
0417 
0418 inline void InlinedStringField::SetNoArena(absl::string_view value) {
0419   get_mutable()->assign(value.data(), value.length());
0420 }
0421 
0422 inline void InlinedStringField::SetNoArena(std::string&& value) {
0423   get_mutable()->assign(std::move(value));
0424 }
0425 
0426 inline PROTOBUF_NDEBUG_INLINE void InlinedStringField::InternalSwap(
0427     InlinedStringField* lhs, bool lhs_arena_dtor_registered,
0428     MessageLite* lhs_msg,  //
0429     InlinedStringField* rhs, bool rhs_arena_dtor_registered,
0430     MessageLite* rhs_msg, Arena* arena) {
0431 #ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
0432   lhs->get_mutable()->swap(*rhs->get_mutable());
0433   if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
0434     lhs_msg->OnDemandRegisterArenaDtor(arena);
0435   } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
0436     rhs_msg->OnDemandRegisterArenaDtor(arena);
0437   }
0438 #else
0439   (void)arena;
0440   (void)lhs_arena_dtor_registered;
0441   (void)rhs_arena_dtor_registered;
0442   (void)lhs_msg;
0443   (void)rhs_msg;
0444   lhs->get_mutable()->swap(*rhs->get_mutable());
0445 #endif
0446 }
0447 
0448 inline void InlinedStringField::Set(absl::string_view value, Arena* arena,
0449                                     bool donated, uint32_t* /*donating_states*/,
0450                                     uint32_t /*mask*/, MessageLite* /*msg*/) {
0451   (void)arena;
0452   (void)donated;
0453   SetNoArena(value);
0454 }
0455 
0456 inline void InlinedStringField::Set(const char* str, ::google::protobuf::Arena* arena,
0457                                     bool donated, uint32_t* donating_states,
0458                                     uint32_t mask, MessageLite* msg) {
0459   Set(absl::string_view(str), arena, donated, donating_states, mask, msg);
0460 }
0461 
0462 inline void InlinedStringField::Set(const char* str, size_t size,
0463                                     ::google::protobuf::Arena* arena, bool donated,
0464                                     uint32_t* donating_states, uint32_t mask,
0465                                     MessageLite* msg) {
0466   Set(absl::string_view{str, size}, arena, donated, donating_states, mask, msg);
0467 }
0468 
0469 inline void InlinedStringField::SetBytes(absl::string_view value, Arena* arena,
0470                                          bool donated,
0471                                          uint32_t* donating_states,
0472                                          uint32_t mask, MessageLite* msg) {
0473   Set(value, arena, donated, donating_states, mask, msg);
0474 }
0475 
0476 inline void InlinedStringField::SetBytes(std::string&& value, Arena* arena,
0477                                          bool donated,
0478                                          uint32_t* donating_states,
0479                                          uint32_t mask, MessageLite* msg) {
0480   Set(std::move(value), arena, donated, donating_states, mask, msg);
0481 }
0482 
0483 inline void InlinedStringField::SetBytes(const char* str,
0484                                          ::google::protobuf::Arena* arena, bool donated,
0485                                          uint32_t* donating_states,
0486                                          uint32_t mask, MessageLite* msg) {
0487   Set(str, arena, donated, donating_states, mask, msg);
0488 }
0489 
0490 inline void InlinedStringField::SetBytes(const void* p, size_t size,
0491                                          ::google::protobuf::Arena* arena, bool donated,
0492                                          uint32_t* donating_states,
0493                                          uint32_t mask, MessageLite* msg) {
0494   Set(static_cast<const char*>(p), size, arena, donated, donating_states, mask,
0495       msg);
0496 }
0497 
0498 template <typename RefWrappedType>
0499 inline void InlinedStringField::Set(
0500     std::reference_wrapper<RefWrappedType> const_string_ref,
0501     ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0502     uint32_t mask, MessageLite* msg) {
0503   Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
0504 }
0505 
0506 template <typename RefWrappedType>
0507 inline void InlinedStringField::SetBytes(
0508     std::reference_wrapper<RefWrappedType> const_string_ref,
0509     ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
0510     uint32_t mask, MessageLite* msg) {
0511   Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
0512 }
0513 
0514 inline std::string* InlinedStringField::UnsafeMutablePointer() {
0515   return get_mutable();
0516 }
0517 
0518 inline std::string* InlinedStringField::Mutable(std::nullptr_t) {
0519   return get_mutable();
0520 }
0521 
0522 inline std::string* InlinedStringField::MutableNoCopy(std::nullptr_t) {
0523   return get_mutable();
0524 }
0525 
0526 }  // namespace internal
0527 }  // namespace protobuf
0528 }  // namespace google
0529 
0530 #include "google/protobuf/port_undef.inc"
0531 
0532 #endif  // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__