Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 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 // This header provides support for a per thread 'reflection mode'.
0009 //
0010 // Some protocol buffer optimizations use interceptors to determine which
0011 // fields are effectively used in the application. These optimizations are
0012 // disabled if certain reflection calls are intercepted as the assumption is
0013 // then that any field data can be accessed.
0014 //
0015 // The 'reflection mode' defined in this header is intended to be used by
0016 // logic such as ad-hoc profilers to indicate that any scoped reflection usage
0017 // is not originating from, or affecting application code. This reflection mode
0018 // can then be used by such interceptors to ignore any reflection calls not
0019 // affecting the application behavior.
0020 
0021 #ifndef GOOGLE_PROTOBUF_REFLECTION_MODE_H__
0022 #define GOOGLE_PROTOBUF_REFLECTION_MODE_H__
0023 
0024 #include <cstddef>
0025 
0026 // Must be included last.
0027 #include "google/protobuf/port_def.inc"
0028 
0029 namespace google {
0030 namespace protobuf {
0031 namespace internal {
0032 
0033 // The ReflectionModes are ordered in observability levels:
0034 // kDefault: Lowest level. All reflection calls are observable.
0035 // kDebugString: Middle level. Only reflection calls in Message::DebugString are
0036 //               observable.
0037 // kDiagnostics: Highest level. No reflection calls are observable.
0038 enum class ReflectionMode {
0039   kDefault,
0040   kDebugString,
0041   kDiagnostics,
0042 };
0043 
0044 // Returns the current ReflectionMode of protobuf for the current thread. This
0045 // reflection mode can be used by interceptors to ignore any reflection calls
0046 // not affecting the application behavior.
0047 // Always returns `kDefault' if the current platform does not support thread
0048 // local data.
0049 ReflectionMode GetReflectionMode();
0050 
0051 // Scoping class to set the specific ReflectionMode for a given scope.
0052 class PROTOBUF_EXPORT ScopedReflectionMode final {
0053  public:
0054   // Sets the current reflection mode, which will be restored at destruction.
0055   // The reflection mode can only be 'elevated' in observability levels.
0056   // For instance, if the current mode is `kDiagnostics` then scope will remain
0057   // unchanged regardless of `mode`.
0058   explicit ScopedReflectionMode(ReflectionMode mode);
0059 
0060   // Restores the previous reflection mode.
0061   ~ScopedReflectionMode();
0062 
0063   // Returns the scoped ReflectionMode for the current thread.
0064   // See `GetReflectionMode()` for more information on purpose and usage.
0065   static ReflectionMode current_reflection_mode();
0066 
0067   // ScopedReflectionMode is only intended to be used as a locally scoped
0068   // instance to set a reflection mode for the code scoped by this instance.
0069   ScopedReflectionMode(const ScopedReflectionMode&) = delete;
0070   ScopedReflectionMode& operator=(const ScopedReflectionMode&) = delete;
0071 
0072  private:
0073 #if !defined(PROTOBUF_NO_THREADLOCAL)
0074   const ReflectionMode previous_mode_;
0075 #if defined(PROTOBUF_USE_DLLS) && defined(_WIN32)
0076   // Thread local variables cannot be exposed through MSVC DLL interface but we
0077   // can wrap them in static functions.
0078   static ReflectionMode& reflection_mode();
0079 #else
0080   PROTOBUF_CONSTINIT static PROTOBUF_THREAD_LOCAL ReflectionMode
0081       reflection_mode_;
0082 #endif  // PROTOBUF_USE_DLLS && _MSC_VER
0083 #endif  // !PROTOBUF_NO_THREADLOCAL
0084 };
0085 
0086 #if !defined(PROTOBUF_NO_THREADLOCAL)
0087 
0088 #if defined(PROTOBUF_USE_DLLS) && defined(_WIN32)
0089 
0090 inline ScopedReflectionMode::ScopedReflectionMode(ReflectionMode mode)
0091     : previous_mode_(reflection_mode()) {
0092   if (mode > reflection_mode()) {
0093     reflection_mode() = mode;
0094   }
0095 }
0096 
0097 inline ScopedReflectionMode::~ScopedReflectionMode() {
0098   reflection_mode() = previous_mode_;
0099 }
0100 
0101 inline ReflectionMode ScopedReflectionMode::current_reflection_mode() {
0102   return reflection_mode();
0103 }
0104 
0105 #else
0106 
0107 inline ScopedReflectionMode::ScopedReflectionMode(ReflectionMode mode)
0108     : previous_mode_(reflection_mode_) {
0109   if (mode > reflection_mode_) {
0110     reflection_mode_ = mode;
0111   }
0112 }
0113 
0114 inline ScopedReflectionMode::~ScopedReflectionMode() {
0115   reflection_mode_ = previous_mode_;
0116 }
0117 
0118 inline ReflectionMode ScopedReflectionMode::current_reflection_mode() {
0119   return reflection_mode_;
0120 }
0121 
0122 #endif  // PROTOBUF_USE_DLLS && _MSC_VER
0123 
0124 #else
0125 
0126 inline ScopedReflectionMode::ScopedReflectionMode(ReflectionMode mode) {}
0127 inline ScopedReflectionMode::~ScopedReflectionMode() {}
0128 inline ReflectionMode ScopedReflectionMode::current_reflection_mode() {
0129   return ReflectionMode::kDefault;
0130 }
0131 
0132 #endif  // !PROTOBUF_NO_THREADLOCAL
0133 
0134 inline ReflectionMode GetReflectionMode() {
0135   return ScopedReflectionMode::current_reflection_mode();
0136 }
0137 
0138 }  // namespace internal
0139 }  // namespace protobuf
0140 }  // namespace google
0141 
0142 #include "google/protobuf/port_undef.inc"
0143 
0144 #endif  // GOOGLE_PROTOBUF_REFLECTION_MODE_H__