// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // This file contains miscellaneous helper code used by generated code -- // including lite types -- but which should not be used directly by users. #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ #include #include #include #include #include #include #include #include #include #include #include // Add direct dep on port for pb.cc #include #include #include #include #include #include #ifdef SWIG #error "You cannot SWIG proto headers" #endif namespace google { namespace protobuf { class Arena; class Message; namespace io { class CodedInputStream; } namespace internal { template inline To DownCast(From* f) { return PROTOBUF_NAMESPACE_ID::internal::down_cast(f); } template inline To DownCast(From& f) { return PROTOBUF_NAMESPACE_ID::internal::down_cast(f); } // This fastpath inlines a single branch instead of having to make the // InitProtobufDefaults function call. // It also generates less inlined code than a function-scope static initializer. PROTOBUF_EXPORT extern std::atomic init_protobuf_defaults_state; PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); PROTOBUF_EXPORT inline void InitProtobufDefaults() { if (PROTOBUF_PREDICT_FALSE( !init_protobuf_defaults_state.load(std::memory_order_acquire))) { InitProtobufDefaultsSlow(); } } // This used by proto1 PROTOBUF_EXPORT inline const std::string& GetEmptyString() { InitProtobufDefaults(); return GetEmptyStringAlreadyInited(); } // True if IsInitialized() is true for all elements of t. Type is expected // to be a RepeatedPtrField. It's useful to have this // helper here to keep the protobuf compiler from ever having to emit loops in // IsInitialized() methods. We want the C++ compiler to inline this or not // as it sees fit. template bool AllAreInitialized(const RepeatedPtrField& t) { for (int i = t.size(); --i >= 0;) { if (!t.Get(i).IsInitialized()) return false; } return true; } // "Weak" variant of AllAreInitialized, used to implement implicit weak fields. // This version operates on MessageLite to avoid introducing a dependency on the // concrete message type. template bool AllAreInitializedWeak(const RepeatedPtrField& t) { for (int i = t.size(); --i >= 0;) { if (!reinterpret_cast(t) .Get >(i) .IsInitialized()) { return false; } } return true; } inline bool IsPresent(const void* base, uint32_t hasbit) { const uint32_t* has_bits_array = static_cast(base); return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0; } inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) { const uint32_t* oneof = reinterpret_cast( static_cast(base) + offset); return *oneof == tag >> 3; } typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset, uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output); PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr, uint32_t offset, uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output); PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base, uint32_t offset, uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output); PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message); PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena, MessageLite* submessage, Arena* submessage_arena); PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2); // We specialize GenericSwap for non-lite messages to benefit from reflection. PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2); template T* DuplicateIfNonNull(T* message) { // The casts must be reinterpret_cast<> because T might be a forward-declared // type that the compiler doesn't know is related to MessageLite. return reinterpret_cast( DuplicateIfNonNullInternal(reinterpret_cast(message))); } template T* GetOwnedMessage(Arena* message_arena, T* submessage, Arena* submessage_arena) { // The casts must be reinterpret_cast<> because T might be a forward-declared // type that the compiler doesn't know is related to MessageLite. return reinterpret_cast(GetOwnedMessageInternal( message_arena, reinterpret_cast(submessage), submessage_arena)); } // Hide atomic from the public header and allow easy change to regular int // on platforms where the atomic might have a perf impact. class PROTOBUF_EXPORT CachedSize { public: int Get() const { return size_.load(std::memory_order_relaxed); } void Set(int size) { size_.store(size, std::memory_order_relaxed); } private: std::atomic size_{0}; }; PROTOBUF_EXPORT void DestroyMessage(const void* message); PROTOBUF_EXPORT void DestroyString(const void* s); // Destroy (not delete) the message inline void OnShutdownDestroyMessage(const void* ptr) { OnShutdownRun(DestroyMessage, ptr); } // Destroy the string (call std::string destructor) inline void OnShutdownDestroyString(const std::string* ptr) { OnShutdownRun(DestroyString, ptr); } } // namespace internal } // namespace protobuf } // namespace google #include #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__