summaryrefslogtreecommitdiff
path: root/upb/bindings/googlepb
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-11-18 15:21:50 -0800
committerJosh Haberman <jhaberman@gmail.com>2014-11-18 15:21:50 -0800
commit3d0c7c45da5b72a88bfb03dc5ce3384b7f01cef6 (patch)
tree1c9fd69700e1162c7ed78458160800b586600c9b /upb/bindings/googlepb
parent648afe3da654b6e08fe6ea26ae520581eb892e23 (diff)
Sync to Google-internal development.
Diffstat (limited to 'upb/bindings/googlepb')
-rw-r--r--upb/bindings/googlepb/bridge.cc1
-rw-r--r--upb/bindings/googlepb/proto1.cc27
-rw-r--r--upb/bindings/googlepb/proto2.cc220
3 files changed, 211 insertions, 37 deletions
diff --git a/upb/bindings/googlepb/bridge.cc b/upb/bindings/googlepb/bridge.cc
index a666ff6..6ae8868 100644
--- a/upb/bindings/googlepb/bridge.cc
+++ b/upb/bindings/googlepb/bridge.cc
@@ -115,6 +115,7 @@ reffed_ptr<FieldDef> DefBuilder::NewFieldDef(const goog::FieldDescriptor* f,
upb_f->set_number(f->number(), &status);
upb_f->set_label(FieldDef::ConvertLabel(f->label()));
upb_f->set_descriptor_type(FieldDef::ConvertDescriptorType(f->type()));
+ upb_f->set_packed(f->options().packed());
#ifdef UPB_GOOGLE3
upb_f->set_lazy(f->options().lazy());
#endif
diff --git a/upb/bindings/googlepb/proto1.cc b/upb/bindings/googlepb/proto1.cc
index 0b46fed..68b572c 100644
--- a/upb/bindings/googlepb/proto1.cc
+++ b/upb/bindings/googlepb/proto1.cc
@@ -30,6 +30,10 @@
#undef private
#undef protected
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+namespace proto2 { class Arena; }
+#endif
+
#include "upb/def.h"
#include "upb/handlers.h"
#include "upb/shim/shim.h"
@@ -448,12 +452,35 @@ class P2R_Handlers {
class RepeatedMessageTypeHandler {
public:
typedef proto2::Message Type;
+#ifndef GOOGLE_PROTOBUF_HAS_ARENAS
// AddAllocated() calls this, but only if other objects are sitting
// around waiting for reuse, which we will not do.
static void Delete(Type* t) {
UPB_UNUSED(t);
assert(false);
}
+#else
+ static ::proto2::Arena* GetArena(Type* t) {
+ return t->GetArena();
+ }
+ static void* GetMaybeArenaPointer(Type* t) {
+ return t->GetMaybeArenaPointer();
+ }
+ static inline Type* NewFromPrototype(
+ const Type* prototype, ::proto2::Arena* arena = NULL) {
+ return prototype->New(arena);
+ }
+ // AddAllocated() calls this, but only if other objects are sitting
+ // around waiting for reuse, which we will not do.
+ static void Delete(Type* t, ::proto2::Arena* arena) {
+ UPB_UNUSED(t);
+ UPB_UNUSED(arena);
+ assert(false);
+ }
+ static void Merge(const Type& from, Type* to) {
+ to->MergeFrom(from);
+ }
+#endif
};
// Closure is a RepeatedPtrField<SubMessageType>*, but we access it through
diff --git a/upb/bindings/googlepb/proto2.cc b/upb/bindings/googlepb/proto2.cc
index 657f802..498ae2d 100644
--- a/upb/bindings/googlepb/proto2.cc
+++ b/upb/bindings/googlepb/proto2.cc
@@ -261,11 +261,64 @@ case goog::FieldDescriptor::cpptype: \
return r->offsets_[index];
}
- class FieldOffset {
+ // Base class that provides access to elements of the message as a whole, such
+ // as the unknown-field set, and is inherited by context classes for specific
+ // field handlers.
+ class FieldDataBase {
+ public:
+ FieldDataBase(const goog::internal::GeneratedMessageReflection* r)
+ : unknown_fields_offset_(r->unknown_fields_offset_)
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ , arena_offset_(r->arena_offset_)
+#endif // GOOGLE_PROTOBUF_HAS_ARENAS
+ {}
+
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ goog::Arena* GetArena(const goog::Message& message) const {
+ if (unknown_fields_offset_ ==
+ goog::internal::GeneratedMessageReflection::
+ kUnknownFieldSetInMetadata) {
+ const goog::internal::InternalMetadataWithArena* metadata =
+ GetConstPointer<goog::internal::InternalMetadataWithArena>(
+ &message, arena_offset_);
+ return metadata->arena();
+ } else if (arena_offset_ !=
+ goog::internal::GeneratedMessageReflection::kNoArenaPointer) {
+ return *GetConstPointer<goog::Arena*>(&message, arena_offset_);
+ } else {
+ return NULL;
+ }
+ }
+
+ goog::UnknownFieldSet* GetUnknownFieldSet(goog::Message* message) const {
+ if (unknown_fields_offset_ ==
+ goog::internal::GeneratedMessageReflection::
+ kUnknownFieldSetInMetadata) {
+ goog::internal::InternalMetadataWithArena* metadata =
+ GetPointer<goog::internal::InternalMetadataWithArena>(
+ message, arena_offset_);
+ return metadata->mutable_unknown_fields();
+ }
+ return GetPointer<goog::UnknownFieldSet>(message, unknown_fields_offset_);
+ }
+#else // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ goog::UnknownFieldSet* GetUnknownFieldSet(goog::Message* message) const {
+ return GetPointer<goog::UnknownFieldSet>(message, unknown_fields_offset_);
+ }
+#endif // ifdef !GOOGLE_PROTOBUF_HAS_ARENAS
+ private:
+ int unknown_fields_offset_;
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ int arena_offset_;
+#endif // GOOGLE_PROTOBUF_HAS_ARENAS
+ };
+
+ class FieldOffset : public FieldDataBase {
public:
FieldOffset(const goog::FieldDescriptor* f,
const goog::internal::GeneratedMessageReflection* r)
- : offset_(GetOffset(f, r)), is_repeated_(f->is_repeated()) {
+ : FieldDataBase(r),
+ offset_(GetOffset(f, r)), is_repeated_(f->is_repeated()) {
if (!is_repeated_) {
int64_t hasbit = GetHasbit(f, r);
hasbyte_ = hasbit / 8;
@@ -293,11 +346,12 @@ case goog::FieldDescriptor::cpptype: \
};
#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- class OneofFieldData {
+ class OneofFieldData : public FieldDataBase {
public:
OneofFieldData(const goog::FieldDescriptor* f,
const goog::internal::GeneratedMessageReflection* r)
- : field_number_offset_(GetOneofDiscriminantOffset(f, r)),
+ : FieldDataBase(r),
+ field_number_offset_(GetOneofDiscriminantOffset(f, r)),
field_number_(f->number()) {
const goog::OneofDescriptor* oneof = f->containing_oneof();
@@ -343,6 +397,40 @@ case goog::FieldDescriptor::cpptype: \
return GetPointer<int32_t>(message, field_number_offset_);
}
+ void ClearOneof(goog::Message* m, const FieldOffset* ofs,
+ int field_number) const {
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ if (GetArena(*m) != NULL) {
+ return;
+ }
+#endif
+ switch (types_.at(field_number)) {
+ case ONEOF_TYPE_NONE:
+ break;
+ case ONEOF_TYPE_STRING:
+ delete *ofs->GetFieldPointer<std::string*>(m);
+ break;
+ case ONEOF_TYPE_MESSAGE:
+ delete *ofs->GetFieldPointer<goog::Message*>(m);
+ break;
+#ifdef UPB_GOOGLE3
+ case ONEOF_TYPE_GLOBALSTRING:
+ delete *ofs->GetFieldPointer<string*>(m);
+ break;
+ case ONEOF_TYPE_CORD:
+ delete *ofs->GetFieldPointer<Cord*>(m);
+ break;
+ case ONEOF_TYPE_STRINGPIECE:
+ delete *ofs->GetFieldPointer<
+ goog::internal::StringPieceField*>(m);
+ break;
+ case ONEOF_TYPE_LAZYFIELD:
+ delete *ofs->GetFieldPointer<goog::internal::LazyField*>(m);
+ break;
+#endif
+ }
+ }
+
// Returns whether this is different than the previous value of the
// field_number; this implies that the current value was freed (if
// necessary) and the caller should allocate a new instance.
@@ -351,30 +439,7 @@ case goog::FieldDescriptor::cpptype: \
if (*field_number == field_number_) {
return false;
} else {
- switch (types_.at(*field_number)) {
- case ONEOF_TYPE_NONE:
- break;
- case ONEOF_TYPE_STRING:
- delete *ofs->GetFieldPointer<std::string*>(m);
- break;
- case ONEOF_TYPE_MESSAGE:
- delete *ofs->GetFieldPointer<goog::Message*>(m);
- break;
-#ifdef UPB_GOOGLE3
- case ONEOF_TYPE_GLOBALSTRING:
- delete *ofs->GetFieldPointer<string*>(m);
- break;
- case ONEOF_TYPE_CORD:
- delete *ofs->GetFieldPointer<Cord*>(m);
- break;
- case ONEOF_TYPE_STRINGPIECE:
- delete *ofs->GetFieldPointer<goog::internal::StringPieceField*>(m);
- break;
- case ONEOF_TYPE_LAZYFIELD:
- delete *ofs->GetFieldPointer<goog::internal::LazyField*>(m);
- break;
-#endif
- }
+ ClearOneof(m, ofs, *field_number);
*field_number = field_number_;
return true;
}
@@ -578,7 +643,6 @@ case goog::FieldDescriptor::cpptype: \
const upb::FieldDef* f)
: FieldOffset(proto2_f, r),
field_number_(f->number()),
- unknown_fields_offset_(r->unknown_fields_offset_),
enum_(upb_downcast_enumdef(f->subdef())) {}
bool IsValidValue(int32_t val) const {
@@ -587,13 +651,8 @@ case goog::FieldDescriptor::cpptype: \
int32_t field_number() const { return field_number_; }
- goog::UnknownFieldSet* mutable_unknown_fields(goog::Message* m) const {
- return GetPointer<goog::UnknownFieldSet>(m, unknown_fields_offset_);
- }
-
private:
int32_t field_number_;
- size_t unknown_fields_offset_;
const upb::EnumDef* enum_;
};
@@ -617,7 +676,7 @@ case goog::FieldDescriptor::cpptype: \
*message_val = val;
data->SetHasbit(m);
} else {
- data->mutable_unknown_fields(m)->AddVarint(data->field_number(), val);
+ data->GetUnknownFieldSet(m)->AddVarint(data->field_number(), val);
}
}
@@ -631,7 +690,7 @@ case goog::FieldDescriptor::cpptype: \
data->GetFieldPointer<goog::RepeatedField<int32_t> >(m);
r->Add(val);
} else {
- data->mutable_unknown_fields(m)->AddVarint(data->field_number(), val);
+ data->GetUnknownFieldSet(m)->AddVarint(data->field_number(), val);
}
}
@@ -718,7 +777,14 @@ case goog::FieldDescriptor::cpptype: \
T** str = data->GetStringPointer(m);
data->SetHasbit(m);
// If it points to the default instance, we must create a new instance.
- if (*str == data->prototype()) *str = new T();
+ if (*str == data->prototype()) {
+ *str = new T();
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ if (data->GetArena(*m)) {
+ data->GetArena(*m)->Own(*str);
+ }
+#endif
+ }
(*str)->clear();
// reserve() here appears to hurt performance rather than help.
return *str;
@@ -749,6 +815,16 @@ case goog::FieldDescriptor::cpptype: \
T** str = ofs->GetFieldPointer<T*>(m);
if (data->SetOneofHas(m)) {
*str = new T();
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ // Note that in the main proto2-arenas implementation, the parsing code
+ // creates ArenaString instances for string field data, and the
+ // implementation later dynamically converts to ::string if a mutable
+ // version is requested. To keep complexity down in this binding, we
+ // create an ordinary string and allow the arena to own its destruction.
+ if (data->GetArena(*m) != NULL) {
+ data->GetArena(*m)->Own(*str);
+ }
+#endif
} else {
(*str)->clear();
}
@@ -857,7 +933,11 @@ case goog::FieldDescriptor::cpptype: \
data->SetHasbit(m);
goog::Message** subm = data->GetFieldPointer<goog::Message*>(m);
if (*subm == NULL || *subm == data->prototype()) {
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ *subm = data->prototype()->New(data->GetArena(*m));
+#else
*subm = data->prototype()->New();
+#endif
}
return *subm;
}
@@ -865,14 +945,50 @@ case goog::FieldDescriptor::cpptype: \
class RepeatedMessageTypeHandler {
public:
typedef goog::Message Type;
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ static ::proto2::Arena* GetArena(Type* t) {
+ return t->GetArena();
+ }
+ static void* GetMaybeArenaPointer(Type* t) {
+ return t->GetMaybeArenaPointer();
+ }
+ static inline Type* NewFromPrototype(
+ const Type* prototype, ::proto2::Arena* arena = NULL) {
+ return prototype->New(arena);
+ }
+ static void Delete(Type* t, goog::Arena* arena = NULL) {
+ if (arena == NULL) {
+ delete t;
+ }
+ }
+#else // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ static inline Type* NewFromPrototype(const Type* prototype) {
+ return prototype->New();
+ }
// AddAllocated() calls this, but only if other objects are sitting
// around waiting for reuse, which we will not do.
static void Delete(Type* t) {
UPB_UNUSED(t);
assert(false);
}
+#endif // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+
+ static void Merge(const Type& from, Type* to) {
+ to->MergeFrom(from);
+ }
};
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ // Closure is a RepeatedPtrField<SubMessageType>*, but we access it through
+ // its base class RepeatedPtrFieldBase*.
+ static goog::Message* StartRepeatedSubMessage(
+ goog::internal::RepeatedPtrFieldBase* r,
+ const SubMessageHandlerData* data) {
+ goog::Message* submsg = data->prototype()->New(r->GetArenaNoVirtual());
+ r->AddAllocated<RepeatedMessageTypeHandler>(submsg);
+ return submsg;
+ }
+#else // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
// Closure is a RepeatedPtrField<SubMessageType>*, but we access it through
// its base class RepeatedPtrFieldBase*.
static goog::Message* StartRepeatedSubMessage(
@@ -886,13 +1002,19 @@ case goog::FieldDescriptor::cpptype: \
return submsg;
}
+#endif // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+
#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
static goog::Message* StartOneofSubMessage(
goog::Message* m, const OneofSubMessageHandlerData* data) {
const FieldOffset* ofs = data;
goog::Message** subm = ofs->GetFieldPointer<goog::Message*>(m);
if (data->SetOneofHas(m)) {
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ *subm = data->prototype()->New(data->GetArena(*m));
+#else
*subm = data->prototype()->New();
+#endif
}
return *subm;
}
@@ -1123,9 +1245,21 @@ case goog::FieldDescriptor::cpptype: \
LazyMessageExtensionImpl() {}
virtual ~LazyMessageExtensionImpl() {}
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ virtual LazyMessageExtension* New() const {
+ return New(NULL);
+ }
+
+ virtual LazyMessageExtension* New(proto2::Arena* arena) const {
+ LazyMessageExtensionImpl* message =
+ ::proto2::Arena::Create<LazyMessageExtensionImpl>(arena);
+ return message;
+ }
+#else // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
virtual LazyMessageExtension* New() const {
return new LazyMessageExtensionImpl();
}
+#endif // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
virtual const proto2::MessageLite& GetMessage(
const proto2::MessageLite& prototype) const {
@@ -1149,6 +1283,12 @@ case goog::FieldDescriptor::cpptype: \
static_cast<const proto2::Message&>(prototype));
}
+ virtual proto2::MessageLite* UnsafeArenaReleaseMessage(
+ const proto2::MessageLite& prototype) {
+ return lazy_field_.UnsafeArenaReleaseByPrototype(
+ static_cast<const proto2::Message&>(prototype));
+ }
+
virtual bool IsInitialized() const { return true; }
virtual int ByteSize() const { return lazy_field_.MessageByteSize(); }
@@ -1201,7 +1341,13 @@ case goog::FieldDescriptor::cpptype: \
LazyMessageExtensionImpl* lazy_extension;
if (set->MaybeNewExtension(data->number(), data->field_descriptor(),
&item)) {
+#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
+ lazy_extension =
+ ::proto2::Arena::Create<LazyMessageExtensionImpl>(
+ m->GetArena());
+#else
lazy_extension = new LazyMessageExtensionImpl();
+#endif
item->type = UPB_DESCRIPTOR_TYPE_MESSAGE;
item->is_repeated = false;
item->is_lazy = true;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback