// Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd #ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ #define UPB_MESSAGE_INTERNAL_TYPES_H_ #include // Must be last. #include "upb/port/def.inc" #define UPB_OPAQUE(x) x##_opaque struct upb_Message { union { uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen double d; // Forces same size for 32-bit/64-bit builds }; }; #ifdef __cplusplus extern "C" { #endif UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( struct upb_Message* msg) { msg->UPB_OPAQUE(internal) |= 1ULL; } UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; } UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( const struct upb_Message* msg) { const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; return (struct upb_Message_Internal*)tmp; } UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( struct upb_Message* msg, struct upb_Message_Internal* internal) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); msg->UPB_OPAQUE(internal) = (uintptr_t)internal; } #ifdef __cplusplus } /* extern "C" */ #endif #undef UPB_OPAQUE #include "upb/port/undef.inc" #endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */