| Index: third_party/protobuf/src/google/protobuf/metadata.h
|
| diff --git a/third_party/protobuf/src/google/protobuf/metadata.h b/third_party/protobuf/src/google/protobuf/metadata.h
|
| index fdee150b44f5c7d92ba1ccf0fc062c4887e65b8c..f9257534eecf4f5589dceb39b308f3779f64ef57 100644
|
| --- a/third_party/protobuf/src/google/protobuf/metadata.h
|
| +++ b/third_party/protobuf/src/google/protobuf/metadata.h
|
| @@ -40,6 +40,8 @@
|
|
|
| #include <google/protobuf/stubs/common.h>
|
| #include <google/protobuf/arena.h>
|
| +#include <google/protobuf/arenastring.h>
|
| +#include <google/protobuf/generated_message_util.h>
|
| #include <google/protobuf/unknown_field_set.h>
|
|
|
| namespace google {
|
| @@ -56,30 +58,30 @@ namespace internal {
|
| // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
|
| // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
|
| // pointer.
|
| -class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
|
| +template <class T, class Derived>
|
| +class InternalMetadataWithArenaBase {
|
| public:
|
| - InternalMetadataWithArena() : ptr_(NULL) {}
|
| - explicit InternalMetadataWithArena(Arena* arena)
|
| - : ptr_ (arena) {}
|
| + InternalMetadataWithArenaBase() : ptr_(NULL) {}
|
| + explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {}
|
|
|
| - ~InternalMetadataWithArena() {
|
| + ~InternalMetadataWithArenaBase() {
|
| if (have_unknown_fields() && arena() == NULL) {
|
| delete PtrValue<Container>();
|
| }
|
| ptr_ = NULL;
|
| }
|
|
|
| - GOOGLE_ATTRIBUTE_ALWAYS_INLINE const UnknownFieldSet& unknown_fields() const {
|
| + GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const {
|
| if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
|
| - return PtrValue<Container>()->unknown_fields_;
|
| + return PtrValue<Container>()->unknown_fields;
|
| } else {
|
| - return *UnknownFieldSet::default_instance();
|
| + return Derived::default_instance();
|
| }
|
| }
|
|
|
| - GOOGLE_ATTRIBUTE_ALWAYS_INLINE UnknownFieldSet* mutable_unknown_fields() {
|
| + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() {
|
| if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
|
| - return &PtrValue<Container>()->unknown_fields_;
|
| + return &PtrValue<Container>()->unknown_fields;
|
| } else {
|
| return mutable_unknown_fields_slow();
|
| }
|
| @@ -87,7 +89,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
|
|
|
| GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
|
| if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
|
| - return PtrValue<Container>()->arena_;
|
| + return PtrValue<Container>()->arena;
|
| } else {
|
| return PtrValue<Arena>();
|
| }
|
| @@ -97,7 +99,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
|
| return PtrTag() == kTagContainer;
|
| }
|
|
|
| - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(InternalMetadataWithArena* other) {
|
| + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) {
|
| // Semantics here are that we swap only the unknown fields, not the arena
|
| // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
|
| // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
|
| @@ -105,7 +107,19 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
|
| // cannot simply swap ptr_ and then restore the arena pointers. We reuse
|
| // UFS's swap implementation instead.
|
| if (have_unknown_fields() || other->have_unknown_fields()) {
|
| - mutable_unknown_fields()->Swap(other->mutable_unknown_fields());
|
| + static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields());
|
| + }
|
| + }
|
| +
|
| + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) {
|
| + if (other.have_unknown_fields()) {
|
| + static_cast<Derived*>(this)->DoMergeFrom(other.unknown_fields());
|
| + }
|
| + }
|
| +
|
| + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() {
|
| + if (have_unknown_fields()) {
|
| + static_cast<Derived*>(this)->DoClear();
|
| }
|
| }
|
|
|
| @@ -131,30 +145,80 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
|
| return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
|
| }
|
|
|
| - template<typename T> T* PtrValue() const {
|
| - return reinterpret_cast<T*>(
|
| + template<typename U> U* PtrValue() const {
|
| + return reinterpret_cast<U*>(
|
| reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask);
|
| }
|
|
|
| // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
|
| struct Container {
|
| - UnknownFieldSet unknown_fields_;
|
| - Arena* arena_;
|
| + T unknown_fields;
|
| + Arena* arena;
|
| };
|
|
|
| - GOOGLE_ATTRIBUTE_NOINLINE UnknownFieldSet* mutable_unknown_fields_slow() {
|
| + GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() {
|
| Arena* my_arena = arena();
|
| Container* container = Arena::Create<Container>(my_arena);
|
| ptr_ = reinterpret_cast<void*>(
|
| reinterpret_cast<intptr_t>(container) | kTagContainer);
|
| - container->arena_ = my_arena;
|
| - return &(container->unknown_fields_);
|
| + container->arena = my_arena;
|
| + return &(container->unknown_fields);
|
| + }
|
| +};
|
| +
|
| +class InternalMetadataWithArena
|
| + : public InternalMetadataWithArenaBase<UnknownFieldSet,
|
| + InternalMetadataWithArena> {
|
| + public:
|
| + InternalMetadataWithArena() {}
|
| + explicit InternalMetadataWithArena(Arena* arena)
|
| + : InternalMetadataWithArenaBase(arena) {}
|
| +
|
| + void DoSwap(UnknownFieldSet* other) {
|
| + mutable_unknown_fields()->Swap(other);
|
| + }
|
| +
|
| + void DoMergeFrom(const UnknownFieldSet& other) {
|
| + mutable_unknown_fields()->MergeFrom(other);
|
| + }
|
| +
|
| + void DoClear() {
|
| + mutable_unknown_fields()->Clear();
|
| + }
|
| +
|
| + static const UnknownFieldSet& default_instance() {
|
| + return *UnknownFieldSet::default_instance();
|
| }
|
| };
|
|
|
| -// Temporary compatibility typedef. Remove once this is released in components
|
| -// and upb CL is submitted.
|
| -typedef InternalMetadataWithArena InternalMetadata;
|
| +// We store unknown fields as a string right now, because there is currently no
|
| +// good interface for reading unknown fields into an ArenaString. We may want
|
| +// to revisit this to allow unknown fields to be parsed onto the Arena.
|
| +class InternalMetadataWithArenaLite
|
| + : public InternalMetadataWithArenaBase<string,
|
| + InternalMetadataWithArenaLite> {
|
| + public:
|
| + InternalMetadataWithArenaLite() {}
|
| +
|
| + explicit InternalMetadataWithArenaLite(Arena* arena)
|
| + : InternalMetadataWithArenaBase(arena) {}
|
| +
|
| + void DoSwap(string* other) {
|
| + mutable_unknown_fields()->swap(*other);
|
| + }
|
| +
|
| + void DoMergeFrom(const string& other) {
|
| + mutable_unknown_fields()->append(other);
|
| + }
|
| +
|
| + void DoClear() {
|
| + mutable_unknown_fields()->clear();
|
| + }
|
| +
|
| + static const string& default_instance() {
|
| + return GetEmptyStringAlreadyInited();
|
| + }
|
| +};
|
|
|
| } // namespace internal
|
| } // namespace protobuf
|
|
|