Remove PROTOBUF_MAYBE_CONSTEXPR and make the constructor constexpr even in MSVC

This solves a conflict when using Clang for Windows.

This is just a cherry-pick of the internal change cl/341698875.
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 9fbd06a..19be23a 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -329,7 +329,7 @@
   // It uses a linker initialized mutex, so it is not compatible with regular
   // runtime instances.
   // Except in MSVC, where we can't have a constinit mutex.
-  explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized)
+  explicit constexpr MapFieldBase(ConstantInitialized)
       : arena_(nullptr),
         repeated_field_(nullptr),
         mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index 320e888..01b3ce3 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -148,9 +148,6 @@
 #ifdef PROTOBUF_CONSTINIT
 #error PROTOBUF_CONSTINIT was previously defined
 #endif
-#ifdef PROTOBUF_MAYBE_CONSTEXPR
-#error PROTOBUF_MAYBE_CONSTEXPR was previously defined
-#endif
 #ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY
 #error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined
 #endif
@@ -560,15 +557,6 @@
 #define PROTOBUF_CONSTINIT
 #endif
 
-// Some constructors can't be constexpr under MSVC, but given that MSVC will not
-// do constant initialization of globals anyway we can omit `constexpr` from
-// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR
-#if defined(_MSC_VER)
-#define PROTOBUF_MAYBE_CONSTEXPR
-#else
-#define PROTOBUF_MAYBE_CONSTEXPR constexpr
-#endif
-
 #if _MSC_VER
 #define PROTOBUF_DISABLE_MSVC_UNION_WARNING \
   __pragma(warning(push)) \
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index d141428..99c05fb 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -75,7 +75,6 @@
 #undef PROTOBUF_DISABLE_MSVC_UNION_WARNING
 #undef PROTOBUF_ENABLE_MSVC_UNION_WARNING
 #undef PROTOBUF_CONSTINIT
-#undef PROTOBUF_MAYBE_CONSTEXPR
 #undef PROTOBUF_ATTRIBUTE_NO_DESTROY
 
 // Restore macro that may have been #undef'd in port_def.inc.
diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
index b222ff7..64c4d6a 100644
--- a/src/google/protobuf/stubs/mutex.h
+++ b/src/google/protobuf/stubs/mutex.h
@@ -90,12 +90,33 @@
 
 #endif
 
+// In MSVC std::mutex does not have a constexpr constructor.
+// This wrapper makes the constructor constexpr.
+template <typename T>
+class CallOnceInitializedMutex {
+ public:
+  constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {}
+  ~CallOnceInitializedMutex() { get().~T(); }
+
+  void lock() { get().lock(); }
+  void unlock() { get().unlock(); }
+
+ private:
+  T& get() {
+    std::call_once(flag_, [&] { ::new (static_cast<void*>(&buf_)) T(); });
+    return reinterpret_cast<T&>(buf_);
+  }
+
+  std::once_flag flag_;
+  alignas(T) char buf_[sizeof(T)];
+};
+
 // Mutex is a natural type to wrap. As both google and other organization have
 // specialized mutexes. gRPC also provides an injection mechanism for custom
 // mutexes.
 class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
  public:
-  WrappedMutex() = default;
+  constexpr WrappedMutex() = default;
   void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
   void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
   // Crash if this Mutex is not held exclusively by this thread.
@@ -103,11 +124,13 @@
   void AssertHeld() const {}
 
  private:
-#ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+#if defined(_MSC_VER)
+  CallOnceInitializedMutex<std::mutex> mu_;
+#elif defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP)
+  CallOnceInitializedMutex<CriticalSectionLock> mu_;
+#else
   std::mutex mu_;
-#else  // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
-  CriticalSectionLock mu_;
-#endif  // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+#endif
 };
 
 using Mutex = WrappedMutex;