From 09354db1434859a31a3c81abebcc4018d42f2715 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Tue, 18 Jul 2017 15:38:30 -0700 Subject: Merge from Google internal for 3.4 release --- src/google/protobuf/message_lite.h | 187 +++++++++++++++++++++++++++++++------ 1 file changed, 160 insertions(+), 27 deletions(-) (limited to 'src/google/protobuf/message_lite.h') diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 046a736d..2075f4b6 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -42,22 +42,130 @@ #include #include #include -#include +#include +#if LANG_CXX11 && !defined(__NVCC__) +#define PROTOBUF_CXX11 1 +#else +#define PROTOBUF_CXX11 0 +#endif + +#if PROTOBUF_CXX11 +#define PROTOBUF_FINAL final +#else +#define PROTOBUF_FINAL +#endif + +#ifndef LIBPROTOBUF_EXPORT +#define LIBPROTOBUF_EXPORT +#endif + +#define PROTOBUF_RUNTIME_DEPRECATED(message) + namespace google { namespace protobuf { - class Arena; +class Arena; namespace io { - class CodedInputStream; - class CodedOutputStream; - class ZeroCopyInputStream; - class ZeroCopyOutputStream; +class CodedInputStream; +class CodedOutputStream; +class ZeroCopyInputStream; +class ZeroCopyOutputStream; } namespace internal { - class WireFormatLite; + +class WireFormatLite; + +#ifndef SWIG +// We compute sizes as size_t but cache them as int. This function converts a +// computed size to a cached size. Since we don't proceed with serialization +// if the total size was > INT_MAX, it is not important what this function +// returns for inputs > INT_MAX. However this case should not error or +// GOOGLE_CHECK-fail, because the full size_t resolution is still returned from +// ByteSizeLong() and checked against INT_MAX; we can catch the overflow +// there. +inline int ToCachedSize(size_t size) { return static_cast(size); } + +// We mainly calculate sizes in terms of size_t, but some functions that +// compute sizes return "int". These int sizes are expected to always be +// positive. This function is more efficient than casting an int to size_t +// directly on 64-bit platforms because it avoids making the compiler emit a +// sign extending instruction, which we don't want and don't want to pay for. +inline size_t FromIntSize(int size) { + // Convert to unsigned before widening so sign extension is not necessary. + return static_cast(size); +} + +// For cases where a legacy function returns an integer size. We GOOGLE_DCHECK() +// that the conversion will fit within an integer; if this is false then we +// are losing information. +inline int ToIntSize(size_t size) { + GOOGLE_DCHECK_LE(size, static_cast(INT_MAX)); + return static_cast(size); } +// This type wraps a variable whose constructor and destructor are explicitly +// called. It is particularly useful for a global variable, without its +// constructor and destructor run on start and end of the program lifetime. +// This circumvents the initial construction order fiasco, while keeping +// the address of the empty string a compile time constant. +// +// Pay special attention to the initialization state of the object. +// 1. The object is "uninitialized" to begin with. +// 2. Call DefaultConstruct() only if the object is uninitialized. +// After the call, the object becomes "initialized". +// 3. Call get() and get_mutable() only if the object is initialized. +// 4. Call Destruct() only if the object is initialized. +// After the call, the object becomes uninitialized. +template +class ExplicitlyConstructed { + public: + void DefaultConstruct() { + new (&union_) T(); + } + + void Destruct() { + get_mutable()->~T(); + } + +#if LANG_CXX11 + constexpr +#endif + const T& + get() const { + return reinterpret_cast(union_); + } + T* get_mutable() { return reinterpret_cast(&union_); } + + private: + // Prefer c++14 aligned_storage, but for compatibility this will do. + union AlignedUnion { + char space[sizeof(T)]; + int64 align_to_int64; + void* align_to_ptr; + } union_; +}; + +// Default empty string object. Don't use this directly. Instead, call +// GetEmptyString() to get the reference. +extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; +LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; +LIBPROTOBUF_EXPORT void InitEmptyString(); + + +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.get(); +} + +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { + ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString); + return GetEmptyStringAlreadyInited(); +} + +LIBPROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const string& str); +#endif // SWIG +} // namespace internal + // Interface to light weight protocol messages. // // This interface is implemented by all protocol message objects. Non-lite @@ -102,18 +210,19 @@ class LIBPROTOBUF_EXPORT MessageLite { // Get the arena, if any, associated with this message. Virtual method // required for generic operations but most arena-related operations should // use the GetArenaNoVirtual() generated-code method. Default implementation - // to reduce code size by avoiding the need for per-type implementations when - // types do not implement arena support. + // to reduce code size by avoiding the need for per-type implementations + // when types do not implement arena support. virtual ::google::protobuf::Arena* GetArena() const { return NULL; } - // Get a pointer that may be equal to this message's arena, or may not be. If - // the value returned by this method is equal to some arena pointer, then this - // message is on that arena; however, if this message is on some arena, this - // method may or may not return that arena's pointer. As a tradeoff, this - // method may be more efficient than GetArena(). The intent is to allow - // underlying representations that use e.g. tagged pointers to sometimes store - // the arena pointer directly, and sometimes in a more indirect way, and allow - // a fastpath comparison against the arena pointer when it's easy to obtain. + // Get a pointer that may be equal to this message's arena, or may not be. + // If the value returned by this method is equal to some arena pointer, then + // this message is on that arena; however, if this message is on some arena, + // this method may or may not return that arena's pointer. As a tradeoff, + // this method may be more efficient than GetArena(). The intent is to allow + // underlying representations that use e.g. tagged pointers to sometimes + // store the arena pointer directly, and sometimes in a more indirect way, + // and allow a fastpath comparison against the arena pointer when it's easy + // to obtain. virtual void* GetMaybeArenaPointer() const { return GetArena(); } // Clear all fields of the message and set them to their default values. @@ -131,19 +240,20 @@ class LIBPROTOBUF_EXPORT MessageLite { // for full messages. See message.h. virtual string InitializationErrorString() const; - // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, // results are undefined (probably crash). virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; // Parsing --------------------------------------------------------- // Methods for parsing in protocol buffer format. Most of these are - // just simple wrappers around MergeFromCodedStream(). Clear() will be called - // before merging the input. - - // Fill the message with a protocol buffer parsed from the given input stream. - // Returns false on a read error or if the input is in the wrong format. A - // successful return does not indicate the entire input is consumed, ensure - // you call ConsumedEntireMessage() to check that if applicable. + // just simple wrappers around MergeFromCodedStream(). Clear() will be + // called before merging the input. + + // Fill the message with a protocol buffer parsed from the given input + // stream. Returns false on a read error or if the input is in the wrong + // format. A successful return does not indicate the entire input is + // consumed, ensure you call ConsumedEntireMessage() to check that if + // applicable. bool ParseFromCodedStream(io::CodedInputStream* input); // Like ParseFromCodedStream(), but accepts messages that are missing // required fields. @@ -249,13 +359,16 @@ class LIBPROTOBUF_EXPORT MessageLite { virtual size_t ByteSizeLong() const = 0; // Legacy ByteSize() API. - int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } + PROTOBUF_RUNTIME_DEPRECATED("Please use ByteSizeLong() instead") + int ByteSize() const { + return internal::ToIntSize(ByteSizeLong()); + } // Serializes the message without recomputing the size. The message must not // have changed since the last call to ByteSize(), and the value returned by // ByteSize must be non-negative. Otherwise the results are undefined. virtual void SerializeWithCachedSizes( - io::CodedOutputStream* output) const = 0; + io::CodedOutputStream* output) const; // Functions below here are not part of the public interface. It isn't // enforced, but they should be treated as private, and will be private @@ -286,11 +399,31 @@ class LIBPROTOBUF_EXPORT MessageLite { uint8* target) const; private: + // TODO(gerbens) make this a pure abstract function + virtual const void* InternalGetTable() const { return NULL; } + friend class internal::WireFormatLite; + friend class Message; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); }; +namespace internal { + +extern bool LIBPROTOBUF_EXPORT proto3_preserve_unknown_; + +// DO NOT USE: For migration only. Will be removed when Proto3 defaults to +// preserve unknowns. +inline bool GetProto3PreserveUnknownsDefault() { + return proto3_preserve_unknown_; +} + +// DO NOT USE: For migration only. Will be removed when Proto3 defaults to +// preserve unknowns. +void LIBPROTOBUF_EXPORT SetProto3PreserveUnknownsDefault(bool preserve); +} // namespace internal + + } // namespace protobuf } // namespace google -- cgit v1.2.3