summaryrefslogtreecommitdiff
path: root/upb/bindings/googlepb
diff options
context:
space:
mode:
Diffstat (limited to 'upb/bindings/googlepb')
-rw-r--r--upb/bindings/googlepb/README20
-rw-r--r--upb/bindings/googlepb/bridge.cc281
-rw-r--r--upb/bindings/googlepb/bridge.h255
-rw-r--r--upb/bindings/googlepb/proto1.cc512
-rw-r--r--upb/bindings/googlepb/proto1.int.h39
-rw-r--r--upb/bindings/googlepb/proto2.cc1395
-rw-r--r--upb/bindings/googlepb/proto2.int.h53
7 files changed, 0 insertions, 2555 deletions
diff --git a/upb/bindings/googlepb/README b/upb/bindings/googlepb/README
deleted file mode 100644
index e3140f4..0000000
--- a/upb/bindings/googlepb/README
+++ /dev/null
@@ -1,20 +0,0 @@
-This directory contains code to interoperate with Google's official
-Protocol Buffers release. Since it doesn't really have a name
-besides "protobuf," calling this directory "googlepb" seems like the
-least confusing option, since it lives in the google::protobuf
-namespace.
-
-We support writing into protobuf's generated classes (and hopefully
-reading too, before long). We support both the open source protobuf
-release and the Google-internal version (which is mostly the same
-code, just in a different namespace). A single compile of upb can
-support both (there are no conflicts thanks to function overloading).
-
-The internal version supports some features that are not supported in
-the open-source release. Also, the internal version includes the
-legacy "proto1" classes which we must support; thankfully this is
-mostly relegated to its own separate file.
-
-Our functionality requires the full google::protobuf::Message
-interface; we rely on reflection so we know what fields to read/write
-and where to put them, so we can't support MessageLite.
diff --git a/upb/bindings/googlepb/bridge.cc b/upb/bindings/googlepb/bridge.cc
deleted file mode 100644
index adba3e7..0000000
--- a/upb/bindings/googlepb/bridge.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-
-// IMPORTANT NOTE! Inside Google, This file is compiled TWICE, once with
-// UPB_GOOGLE3 defined and once without! This allows us to provide
-// functionality against proto2 and protobuf opensource both in a single binary
-// without the two conflicting. However we must be careful not to violate the
-// ODR.
-
-#include "upb/bindings/googlepb/bridge.h"
-
-#include <stdio.h>
-#include <map>
-#include <string>
-#include "upb/def.h"
-#include "upb/bindings/googlepb/proto1.int.h"
-#include "upb/bindings/googlepb/proto2.int.h"
-#include "upb/handlers.h"
-
-#define ASSERT_STATUS(status) do { \
- if (!upb_ok(status)) { \
- fprintf(stderr, "upb status failure: %s\n", upb_status_errmsg(status)); \
- UPB_ASSERT(upb_ok(status)); \
- } \
- } while (0)
-
-#ifdef UPB_GOOGLE3
-#include "net/proto2/public/descriptor.h"
-#include "net/proto2/public/message.h"
-#include "net/proto2/proto/descriptor.pb.h"
-namespace goog = ::proto2;
-#else
-#include "google/protobuf/descriptor.h"
-#include "google/protobuf/message.h"
-#include "google/protobuf/descriptor.pb.h"
-namespace goog = ::google::protobuf;
-#endif
-
-namespace upb {
-namespace googlepb {
-
-const goog::Message* TryGetFieldPrototype(const goog::Message& m,
- const goog::FieldDescriptor* f) {
- const goog::Message* ret = upb::googlepb::GetProto2FieldPrototype(m, f);
-#ifdef UPB_GOOGLE3
- if (!ret) ret = upb::googlepb::GetProto1FieldPrototype(m, f);
-#endif
- return ret;
-}
-
-const goog::Message* GetFieldPrototype(const goog::Message& m,
- const goog::FieldDescriptor* f) {
- const goog::Message* ret = TryGetFieldPrototype(m, f);
- UPB_ASSERT(ret);
- return ret;
-}
-
-/* DefBuilder ****************************************************************/
-
-const EnumDef* DefBuilder::GetEnumDef(const goog::EnumDescriptor* ed) {
- const EnumDef* cached = FindInCache<EnumDef>(ed);
- if (cached) return cached;
-
- EnumDef* e = AddToCache(ed, EnumDef::New());
-
- Status status;
- e->set_full_name(ed->full_name(), &status);
- for (int i = 0; i < ed->value_count(); i++) {
- const goog::EnumValueDescriptor* val = ed->value(i);
- bool success = e->AddValue(val->name(), val->number(), &status);
- UPB_ASSERT(success);
- }
-
- e->Freeze(&status);
-
- ASSERT_STATUS(&status);
- return e;
-}
-
-const MessageDef* DefBuilder::GetMaybeUnfrozenMessageDef(
- const goog::Descriptor* d, const goog::Message* m) {
- const MessageDef* cached = FindInCache<MessageDef>(d);
- if (cached) return cached;
-
- MessageDef* md = AddToCache(d, MessageDef::New());
- to_freeze_.push_back(upb::upcast(md));
-
- Status status;
- md->set_full_name(d->full_name(), &status);
- ASSERT_STATUS(&status);
-
- // Find all regular fields and extensions for this message.
- std::vector<const goog::FieldDescriptor*> fields;
- d->file()->pool()->FindAllExtensions(d, &fields);
- for (int i = 0; i < d->field_count(); i++) {
- fields.push_back(d->field(i));
- }
-
- for (size_t i = 0; i < fields.size(); i++) {
- const goog::FieldDescriptor* proto2_f = fields[i];
- UPB_ASSERT(proto2_f);
- md->AddField(NewFieldDef(proto2_f, m), &status);
- }
- ASSERT_STATUS(&status);
- return md;
-}
-
-reffed_ptr<FieldDef> DefBuilder::NewFieldDef(const goog::FieldDescriptor* f,
- const goog::Message* m) {
- reffed_ptr<FieldDef> upb_f(FieldDef::New());
- Status status;
- 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
-
- if (f->is_extension()) {
- upb_f->set_name(f->full_name(), &status);
- upb_f->set_is_extension(true);
- } else {
- upb_f->set_name(f->name(), &status);
- }
-
- const goog::Message* subm = NULL;
-
- if (m) {
- subm = TryGetFieldPrototype(*m, f);
-
- if (upb_f->type() == UPB_TYPE_MESSAGE) {
- UPB_ASSERT(subm);
- } else if (subm) {
- // Weak field: subm will be weak prototype even though the proto2
- // descriptor does not indicate a submessage field.
- upb_f->set_descriptor_type(UPB_DESCRIPTOR_TYPE_MESSAGE);
- }
- }
-
- switch (upb_f->type()) {
- case UPB_TYPE_INT32:
- upb_f->set_default_int32(f->default_value_int32());
- break;
- case UPB_TYPE_INT64:
- upb_f->set_default_int64(f->default_value_int64());
- break;
- case UPB_TYPE_UINT32:
- upb_f->set_default_uint32(f->default_value_uint32());
- break;
- case UPB_TYPE_UINT64:
- upb_f->set_default_uint64(f->default_value_uint64());
- break;
- case UPB_TYPE_DOUBLE:
- upb_f->set_default_double(f->default_value_double());
- break;
- case UPB_TYPE_FLOAT:
- upb_f->set_default_float(f->default_value_float());
- break;
- case UPB_TYPE_BOOL:
- upb_f->set_default_bool(f->default_value_bool());
- break;
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- upb_f->set_default_string(f->default_value_string(), &status);
- break;
- case UPB_TYPE_MESSAGE: {
- const goog::Descriptor* subd =
- subm ? subm->GetDescriptor() : f->message_type();
- upb_f->set_message_subdef(GetMaybeUnfrozenMessageDef(subd, subm),
- &status);
- break;
- }
- case UPB_TYPE_ENUM:
- // We set the enum default numerically.
- upb_f->set_default_int32(f->default_value_enum()->number());
- upb_f->set_enum_subdef(GetEnumDef(f->enum_type()), &status);
- break;
- }
-
- ASSERT_STATUS(&status);
- return upb_f;
-}
-
-void DefBuilder::Freeze() {
- upb::Status status;
- upb::Def::Freeze(to_freeze_, &status);
- ASSERT_STATUS(&status);
- to_freeze_.clear();
-}
-
-const MessageDef* DefBuilder::GetMessageDef(const goog::Descriptor* d) {
- const MessageDef* ret = GetMaybeUnfrozenMessageDef(d, NULL);
- Freeze();
- return ret;
-}
-
-const MessageDef* DefBuilder::GetMessageDefExpandWeak(
- const goog::Message& m) {
- const MessageDef* ret = GetMaybeUnfrozenMessageDef(m.GetDescriptor(), &m);
- Freeze();
- return ret;
-}
-
-
-/* WriteHandlers *************************************************************/
-
-// static
-bool WriteHandlers::AddFieldHandler(const goog::Message& m,
- const goog::FieldDescriptor* f,
- upb::Handlers* h) {
- const FieldDef* upb_f = h->message_def()->FindFieldByNumber(f->number());
- if (!upb_f) return false;
- if (upb::googlepb::TrySetWriteHandlers(f, m, upb_f, h)) return true;
-#ifdef UPB_GOOGLE3
- if (upb::googlepb::TrySetProto1WriteHandlers(f, m, upb_f, h)) return true;
-#endif
-
- // Unsupported reflection class.
- //
- // Should we fall back to using the public Reflection interface in this
- // case? It's unclear whether it's supported behavior for users to
- // create their own Reflection classes.
- return false;
-}
-
-// static
-upb::reffed_ptr<const upb::Handlers> WriteHandlers::New(
- const goog::Message& m) {
- CodeCache cache;
- return upb::reffed_ptr<const upb::Handlers>(cache.GetWriteHandlers(m));
-}
-
-
-/* CodeCache *****************************************************************/
-
-const Handlers* CodeCache::GetMaybeUnfrozenWriteHandlers(
- const MessageDef* md, const goog::Message& m) {
- const Handlers* cached = FindInCache(md);
- if (cached) return cached;
-
- Handlers* h = AddToCache(md, upb::Handlers::New(md));
- to_freeze_.push_back(h);
- const goog::Descriptor* d = m.GetDescriptor();
-
- for (upb::MessageDef::const_field_iterator i = md->field_begin();
- i != md->field_end(); ++i) {
- const FieldDef* upb_f = *i;
-
- const goog::FieldDescriptor* proto2_f =
- d->FindFieldByNumber(upb_f->number());
- if (!proto2_f) {
- proto2_f = d->file()->pool()->FindExtensionByNumber(d, upb_f->number());
- }
- UPB_ASSERT(proto2_f);
-
- bool ok = WriteHandlers::AddFieldHandler(m, proto2_f, h);
- UPB_ASSERT(ok);
-
- if (upb_f->type() == UPB_TYPE_MESSAGE) {
- const goog::Message* prototype = GetFieldPrototype(m, proto2_f);
- UPB_ASSERT(prototype);
- const upb::Handlers* sub_handlers =
- GetMaybeUnfrozenWriteHandlers(upb_f->message_subdef(), *prototype);
- h->SetSubHandlers(upb_f, sub_handlers);
- }
- }
-
- return h;
-}
-
-const Handlers* CodeCache::GetWriteHandlers(const goog::Message& m) {
- const MessageDef* md = def_builder_.GetMessageDefExpandWeak(m);
- const Handlers* ret = GetMaybeUnfrozenWriteHandlers(md, m);
- upb::Status status;
- upb::Handlers::Freeze(to_freeze_, &status);
- ASSERT_STATUS(&status);
- to_freeze_.clear();
- return ret;
-}
-
-} // namespace googlepb
-} // namespace upb
diff --git a/upb/bindings/googlepb/bridge.h b/upb/bindings/googlepb/bridge.h
deleted file mode 100644
index ce55dc6..0000000
--- a/upb/bindings/googlepb/bridge.h
+++ /dev/null
@@ -1,255 +0,0 @@
-//
-// upb::googlepb::DefBuilder
-// upb::googlepb::WriteHandlers
-// upb::googlepb::CodeCache
-//
-// This file contains functionality for constructing upb Defs and Handlers
-// corresponding to proto2 messages. Using this functionality, you can use upb
-// to dynamically generate parsing code that can behave exactly like proto2's
-// generated parsing code. Alternatively, you can configure things to
-// read/write only a subset of the fields for higher performance when only some
-// fields are needed.
-//
-// Example usage:
-//
-// // JIT the parser; should only be done once ahead-of-time.
-// upb::reffed_ptr<const upb::Handlers> write_myproto(
-// upb::google::NewWriteHandlers(MyProto()));
-// upb::reffed_ptr<const upb::Handlers> parse_myproto(
-// upb::Decoder::NewDecoderHandlers(write_myproto.get(), true));
-//
-// // The actual parsing.
-// MyProto proto;
-// upb::SeededPipeline<8192> pipeline(upb_realloc, NULL);
-// upb::Sink* write_sink = pipeline.NewSink(write_myproto.get());
-// upb::Sink* parse_sink = pipeline.NewSink(parse_myproto.get());
-// upb::pb::Decoder* decoder = decoder_sink->GetObject<upb::pb::Decoder>();
-// upb::pb::ResetDecoderSink(decoder, write_sink);
-// write_sink->Reset(&proto);
-//
-// Note that there is currently no support for
-// CodedInputStream::SetExtensionRegistry(), which allows specifying a separate
-// DescriptorPool and MessageFactory for extensions. Since this is a property
-// of the input in proto2, it's difficult to build a plan ahead-of-time that
-// can properly support this. If it's an important use case, the caller should
-// probably build a upb plan explicitly.
-
-#ifndef UPB_GOOGLE_BRIDGE_H_
-#define UPB_GOOGLE_BRIDGE_H_
-
-#include <map>
-#include <vector>
-#include "upb/handlers.h"
-#include "upb/upb.h"
-
-namespace google {
-namespace protobuf {
-class FieldDescriptor;
-class Descriptor;
-class EnumDescriptor;
-class Message;
-} // namespace protobuf
-} // namespace google
-
-namespace proto2 {
-class FieldDescriptor;
-class Descriptor;
-class EnumDescriptor;
-class Message;
-}
-
-namespace upb {
-
-namespace googlepb {
-
-// Builds upb::Defs from proto2::Descriptors, and caches all built Defs for
-// reuse. CodeCache (below) uses this internally; there is no need to use this
-// class directly unless you only want Defs without corresponding Handlers.
-//
-// This class is NOT thread-safe.
-class DefBuilder {
- public:
- // Functions to get or create a Def from a corresponding proto2 Descriptor.
- // The returned def will be frozen.
- //
- // The caller must take a ref on the returned value if it needs it long-term.
- // The DefBuilder will retain a ref so it can keep the Def cached, but
- // garbage-collection functionality may be added to DefBuilder later that
- // could unref the returned pointer.
- const EnumDef* GetEnumDef(const proto2::EnumDescriptor* d);
- const EnumDef* GetEnumDef(const ::google::protobuf::EnumDescriptor* d);
- const MessageDef* GetMessageDef(const proto2::Descriptor* d);
- const MessageDef* GetMessageDef(const ::google::protobuf::Descriptor* d);
-
- // Gets or creates a frozen MessageDef, properly expanding weak fields.
- //
- // Weak fields are only represented as BYTES fields in the Descriptor (unless
- // you construct your descriptors in a somewhat complicated way; see
- // https://goto.google.com/weak-field-descriptor), but we can get their true
- // definitions relatively easily from the proto Message class.
- const MessageDef* GetMessageDefExpandWeak(const proto2::Message& m);
- const MessageDef* GetMessageDefExpandWeak(
- const ::google::protobuf::Message& m);
-
- // Static methods for converting a def without building a DefBuilder.
- static reffed_ptr<const MessageDef> NewMessageDef(
- const proto2::Descriptor* d) {
- DefBuilder builder;
- return reffed_ptr<const MessageDef>(builder.GetMessageDef(d));
- }
-
- private:
- // Like GetMessageDef*(), except the returned def might not be frozen.
- // We need this function because circular graphs of MessageDefs need to all
- // be frozen together, to we have to create the graphs of defs in an unfrozen
- // state first.
- //
- // If m is non-NULL, expands weak message fields.
- const MessageDef* GetMaybeUnfrozenMessageDef(const proto2::Descriptor* d,
- const proto2::Message* m);
- const MessageDef* GetMaybeUnfrozenMessageDef(
- const ::google::protobuf::Descriptor* d,
- const ::google::protobuf::Message* m);
-
- // Returns a new-unfrozen FieldDef corresponding to this FieldDescriptor.
- // The return value is always newly created (never cached) and the returned
- // pointer is the only owner of it.
- //
- // If "m" is non-NULL, expands the weak field if it is one, and populates
- // *subm_prototype with a prototype of the submessage if this is a weak or
- // non-weak MESSAGE or GROUP field.
- reffed_ptr<FieldDef> NewFieldDef(const proto2::FieldDescriptor* f,
- const proto2::Message* m);
- reffed_ptr<FieldDef> NewFieldDef(const ::google::protobuf::FieldDescriptor* f,
- const ::google::protobuf::Message* m);
-
- // Freeze all defs that haven't been frozen yet.
- void Freeze();
-
- template <class T>
- T* AddToCache(const void *proto2_descriptor, reffed_ptr<T> def) {
- UPB_ASSERT(def_cache_.find(proto2_descriptor) == def_cache_.end());
- def_cache_[proto2_descriptor] = def;
- return def.get(); // Continued lifetime is guaranteed by cache.
- }
-
- template <class T>
- const T* FindInCache(const void *proto2_descriptor) {
- DefCache::iterator iter = def_cache_.find(proto2_descriptor);
- return iter == def_cache_.end() ? NULL :
- upb::down_cast<const T*>(iter->second.get());
- }
-
- private:
- // Maps a proto2 descriptor to the corresponding upb Def we have constructed.
- // The proto2 descriptor is void* because the proto2 descriptor types do not
- // share a common base.
- typedef std::map<const void*, reffed_ptr<upb::Def> > DefCache;
- DefCache def_cache_;
-
- // Defs that have not been frozen yet.
- std::vector<Def*> to_freeze_;
-};
-
-// Handlers to populate a proto2::Message with incoming data.
-class WriteHandlers {
- public:
- // Returns a upb::Handlers object that can be used to populate a
- // proto2::Message object of the same type as "m." For more control over
- // handler caching and reuse, instantiate a CodeCache object below.
- static upb::reffed_ptr<const upb::Handlers> New(const proto2::Message& m);
- static upb::reffed_ptr<const upb::Handlers> New(
- const ::google::protobuf::Message& m);
-
- // TODO(haberman): add an interface that takes a list of field paths,
- // something like:
- //
- // // Returns a Handlers instance that will populate the given field paths
- // // only, dropping data for all other field paths on the floor.
- // static upb::reffed_ptr<const upb::Handlers> New(
- // const proto2::Message& m,
- // const std::vector<std::string>& paths);
-
- // A lower-level interface with field granularity.
- //
- // Adds a handler to the given upb::Handlers for parsing the given field. If
- // you only want to write certain fields into the proto2 message at parse
- // time, call these methods ONLY for the fields you want to parse.
- //
- // The given field can be either a regular field or an extension, as long as
- // its containing_type() matches this message.
- static bool AddFieldHandler(const proto2::Message& m,
- const proto2::FieldDescriptor* f,
- upb::Handlers* h);
- static bool AddFieldHandler(const ::google::protobuf::Message& m,
- const ::google::protobuf::FieldDescriptor* f,
- upb::Handlers* h);
-};
-
-// Builds and caches upb::Handlers for populating proto2 generated classes.
-//
-// This class is NOT thread-safe.
-class CodeCache {
- public:
- // Gets or creates handlers for populating messages of the given message type.
- //
- // The caller must take a ref on the returned value if it needs it long-term.
- // The CodeCache will retain a ref so it can keep the Def cached, but
- // garbage-collection functionality may be added to CodeCache later that could
- // unref the returned pointer.
- const Handlers* GetWriteHandlers(const proto2::Message& m);
- const Handlers* GetWriteHandlers(const ::google::protobuf::Message& m);
-
- private:
- const Handlers* GetMaybeUnfrozenWriteHandlers(const MessageDef* md,
- const proto2::Message& m);
- const Handlers* GetMaybeUnfrozenWriteHandlers(
- const MessageDef* md, const ::google::protobuf::Message& m);
-
- Handlers* AddToCache(const MessageDef* md, reffed_ptr<Handlers> handlers) {
- UPB_ASSERT(handlers_cache_.find(md) == handlers_cache_.end());
- handlers_cache_[md] = handlers;
- return handlers.get(); // Continue lifetime is guaranteed by the cache.
- }
-
- const Handlers* FindInCache(const MessageDef* md) {
- HandlersCache::iterator iter = handlers_cache_.find(md);
- return iter == handlers_cache_.end() ? NULL : iter->second.get();
- }
-
- DefBuilder def_builder_;
-
- typedef std::map<const MessageDef*, upb::reffed_ptr<const Handlers> >
- HandlersCache;
- HandlersCache handlers_cache_;
-
- std::vector<Handlers*> to_freeze_;
-};
-
-// Functions for getting prototypes; these are only necessary if you are
-// building handlers manually, field by field.
-
-// Given a message and a field descriptor for that message, returns a prototype
-// for the submessage. Requires that this is a submessage field or a weak
-// field.
-const proto2::Message* GetFieldPrototype(const proto2::Message& m,
- const proto2::FieldDescriptor* f);
-const ::google::protobuf::Message* GetFieldPrototype(
- const ::google::protobuf::Message& m,
- const ::google::protobuf::FieldDescriptor* f);
-
-// Given a message and a field descriptor for that message, returns a prototype
-// for the submessage, or NULL if this is not a submessage field or a weak
-// field. If this returns non-NULL even though the descriptor's type is not a
-// submessage, then this is a weak field. If you don't know what a weak field
-// is, you are probably not using one.
-const proto2::Message* TryGetFieldPrototype(const proto2::Message& m,
- const proto2::FieldDescriptor* f);
-const ::google::protobuf::Message* TryGetFieldPrototype(
- const ::google::protobuf::Message& m,
- const ::google::protobuf::FieldDescriptor* f);
-
-} // namespace googlepb
-} // namespace upb
-
-#endif // UPB_GOOGLE_BRIDGE_H_
diff --git a/upb/bindings/googlepb/proto1.cc b/upb/bindings/googlepb/proto1.cc
deleted file mode 100644
index c85bfca..0000000
--- a/upb/bindings/googlepb/proto1.cc
+++ /dev/null
@@ -1,512 +0,0 @@
-//
-// This set of handlers can write into a proto2::Message whose reflection class
-// is _pi::Proto2Reflection (ie. proto1 messages; while slightly confusing, the
-// name "Proto2Reflection" indicates that it is a reflection class implementing
-// the proto2 reflection interface, but is used for proto1 generated messages).
-//
-// Like FieldAccessor this depends on breaking encapsulation, and will need to
-// be changed if and when the details of _pi::Proto2Reflection change.
-//
-// Note that we have received an exception from c-style-artiters regarding
-// dynamic_cast<> in this file:
-// https://groups.google.com/a/google.com/d/msg/c-style/7Zp_XCX0e7s/I6dpzno4l-MJ
-
-#include "upb/bindings/googlepb/proto1.int.h"
-
-#include <memory>
-
-// TEMPORARY measure until we update the friend declarations in proto1.
-// Can't do in a single CL because of components.
-#define private public
-#define protected public
-#include "net/proto2/public/repeated_field.h"
-#include "net/proto/internal_layout.h"
-#include "net/proto/proto2_reflection.h"
-#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"
-#include "upb/sink.h"
-
-// Unconditionally evaluate, but also assert in debug mode.
-#define CHKRET(x) do { bool ok = (x); UPB_ASSERT(ok); } while (0)
-
-template <class T> static T* GetPointer(void* message, size_t offset) {
- return reinterpret_cast<T*>(static_cast<char*>(message) + offset);
-}
-
-namespace upb {
-namespace googlepb {
-
-class P2R_Handlers {
- public:
- // Returns true if we were able to set an accessor and any other properties
- // of the FieldDef that are necessary to read/write this field to a
- // proto2::Message.
- static bool TrySet(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& m, const upb::FieldDef* upb_f,
- upb::Handlers* h) {
- const proto2::Reflection* base_r = m.GetReflection();
- // See file comment re: dynamic_cast.
- const _pi::Proto2Reflection* r =
- dynamic_cast<const _pi::Proto2Reflection*>(base_r);
- if (!r) return false;
- // Extensions don't exist in proto1.
- UPB_ASSERT(!proto2_f->is_extension());
-
-#define PRIMITIVE(name, type_name) \
- case _pi::CREP_REQUIRED_##name: \
- case _pi::CREP_OPTIONAL_##name: \
- case _pi::CREP_REPEATED_##name: \
- SetPrimitiveHandlers<type_name>(proto2_f, r, upb_f, h); \
- return true;
-
- switch (r->GetFieldLayout(proto2_f)->crep) {
- PRIMITIVE(DOUBLE, double);
- PRIMITIVE(FLOAT, float);
- PRIMITIVE(INT64, int64_t);
- PRIMITIVE(UINT64, uint64_t);
- PRIMITIVE(INT32, int32_t);
- PRIMITIVE(FIXED64, uint64_t);
- PRIMITIVE(FIXED32, uint32_t);
- PRIMITIVE(BOOL, bool);
- case _pi::CREP_REQUIRED_STRING:
- case _pi::CREP_OPTIONAL_STRING:
- case _pi::CREP_REPEATED_STRING:
- SetStringHandlers(proto2_f, r, upb_f, h);
- return true;
- case _pi::CREP_OPTIONAL_OUTOFLINE_STRING:
- SetOutOfLineStringHandlers(proto2_f, r, upb_f, h);
- return true;
- case _pi::CREP_REQUIRED_CORD:
- case _pi::CREP_OPTIONAL_CORD:
- case _pi::CREP_REPEATED_CORD:
- SetCordHandlers(proto2_f, r, upb_f, h);
- return true;
- case _pi::CREP_REQUIRED_GROUP:
- case _pi::CREP_REQUIRED_FOREIGN:
- case _pi::CREP_REQUIRED_FOREIGN_PROTO2:
- SetRequiredMessageHandlers(proto2_f, m, r, upb_f, h);
- return true;
- case _pi::CREP_OPTIONAL_GROUP:
- case _pi::CREP_REPEATED_GROUP:
- case _pi::CREP_OPTIONAL_FOREIGN:
- case _pi::CREP_REPEATED_FOREIGN:
- case _pi::CREP_OPTIONAL_FOREIGN_PROTO2:
- case _pi::CREP_REPEATED_FOREIGN_PROTO2:
- SetMessageHandlers(proto2_f, m, r, upb_f, h);
- return true;
- case _pi::CREP_OPTIONAL_FOREIGN_WEAK:
- case _pi::CREP_OPTIONAL_FOREIGN_WEAK_PROTO2:
- SetWeakMessageHandlers(proto2_f, m, r, upb_f, h);
- return true;
- default:
- UPB_ASSERT(false);
- return false;
- }
- }
-
-#undef PRIMITIVE
-
- // If the field "f" in the message "m" is a weak field, returns the prototype
- // of the submessage (which may be a specific type or may be OpaqueMessage).
- // Otherwise returns NULL.
- static const proto2::Message* GetWeakPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f) {
- // See file comment re: dynamic_cast.
- const _pi::Proto2Reflection* r =
- dynamic_cast<const _pi::Proto2Reflection*>(m.GetReflection());
- if (!r) return NULL;
-
- const _pi::Field* field = r->GetFieldLayout(f);
- if (field->crep == _pi::CREP_OPTIONAL_FOREIGN_WEAK) {
- return static_cast<const proto2::Message*>(
- field->weak_layout()->default_instance);
- } else if (field->crep == _pi::CREP_OPTIONAL_FOREIGN_WEAK_PROTO2) {
- return field->proto2_weak_default_instance();
- } else {
- return NULL;
- }
- }
-
- // If "m" is a message that uses Proto2Reflection, returns the prototype of
- // the submessage (which may be OpaqueMessage for a weak field that is not
- // linked in). Otherwise returns NULL.
- static const proto2::Message* GetFieldPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f) {
- // See file comment re: dynamic_cast.
- const proto2::Message* ret = GetWeakPrototype(m, f);
- if (ret) {
- return ret;
- } else if (dynamic_cast<const _pi::Proto2Reflection*>(m.GetReflection())) {
- // Since proto1 has no dynamic message, it must be from the generated
- // factory.
- UPB_ASSERT(f->cpp_type() == proto2::FieldDescriptor::CPPTYPE_MESSAGE);
- ret = proto2::MessageFactory::generated_factory()->GetPrototype(
- f->message_type());
- UPB_ASSERT(ret);
- return ret;
- } else {
- return NULL;
- }
- }
-
- private:
- class FieldOffset {
- public:
- FieldOffset(const proto2::FieldDescriptor* f,
- const _pi::Proto2Reflection* r)
- : offset_(GetOffset(f, r)), is_repeated_(f->is_repeated()) {
- if (!is_repeated_) {
- int64_t hasbit = GetHasbit(f, r);
- hasbyte_ = hasbit / 8;
- mask_ = 1 << (hasbit % 8);
- }
- }
-
- template <class T> T* GetFieldPointer(proto2::Message* message) const {
- return GetPointer<T>(message, offset_);
- }
-
- void SetHasbit(void* message) const {
- UPB_ASSERT(!is_repeated_);
- uint8_t* byte = GetPointer<uint8_t>(message, hasbyte_);
- *byte |= mask_;
- }
-
- private:
- const size_t offset_;
- bool is_repeated_;
-
- // Only for non-repeated fields.
- int32_t hasbyte_;
- int8_t mask_;
- };
-
- static upb_selector_t GetSelector(const upb::FieldDef* f,
- upb::Handlers::Type type) {
- upb::Handlers::Selector selector;
- bool ok = upb::Handlers::GetSelector(f, type, &selector);
- UPB_ASSERT(ok);
- return selector;
- }
-
- static int16_t GetHasbit(const proto2::FieldDescriptor* f,
- const _pi::Proto2Reflection* r) {
- UPB_ASSERT(!f->is_repeated());
- return (r->layout_->has_bit_offset * 8) + r->GetFieldLayout(f)->has_index;
- }
-
- static uint16_t GetOffset(const proto2::FieldDescriptor* f,
- const _pi::Proto2Reflection* r) {
- return r->GetFieldLayout(f)->offset;
- }
-
- // StartSequence /////////////////////////////////////////////////////////////
-
- template <class T>
- static void SetStartRepeatedField(
- const proto2::FieldDescriptor* proto2_f, const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBindT(PushOffset<proto2::RepeatedField<T> >,
- new FieldOffset(proto2_f, r))));
- }
-
- template <class T>
- static void SetStartRepeatedPtrField(
- const proto2::FieldDescriptor* proto2_f, const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBindT(PushOffset<proto2::RepeatedPtrField<T> >,
- new FieldOffset(proto2_f, r))));
- }
-
- static void SetStartRepeatedSubmessageField(
- const proto2::FieldDescriptor* proto2_f, const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBind(PushOffset<proto2::internal::RepeatedPtrFieldBase>,
- new FieldOffset(proto2_f, r))));
- }
-
- template <class T>
- static T* PushOffset(proto2::Message* m, const FieldOffset* offset) {
- return offset->GetFieldPointer<T>(m);
- }
-
- // Primitive Value (numeric, enum, bool) /////////////////////////////////////
-
- template <typename T>
- static void SetPrimitiveHandlers(const proto2::FieldDescriptor* proto2_f,
- const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- if (f->IsSequence()) {
- SetStartRepeatedField<T>(proto2_f, r, f, h);
- CHKRET(h->SetValueHandler<T>(f, UpbMakeHandlerT(Append<T>)));
- } else {
- CHKRET(
- upb::Shim::Set(h, f, GetOffset(proto2_f, r), GetHasbit(proto2_f, r)));
- }
- }
-
- template <typename T>
- static void Append(proto2::RepeatedField<T>* r, T val) {
- // Proto1's ProtoArray class derives from proto2::RepeatedField.
- r->Add(val);
- }
-
- // String ////////////////////////////////////////////////////////////////////
-
- static void SetStringHandlers(const proto2::FieldDescriptor* proto2_f,
- const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- h->SetStringHandler(f, UpbMakeHandler(OnStringBuf));
- if (f->IsSequence()) {
- SetStartRepeatedPtrField<string>(proto2_f, r, f, h);
- CHKRET(h->SetStartStringHandler(f, UpbMakeHandler(StartRepeatedString)));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartString, new FieldOffset(proto2_f, r))));
- }
- }
-
- static string* StartString(proto2::Message* m, const FieldOffset* info,
- size_t size_hint) {
- info->SetHasbit(m);
- string* str = info->GetFieldPointer<string>(m);
- str->clear();
- // reserve() here appears to hurt performance rather than help.
- return str;
- }
-
- static void OnStringBuf(string* s, const char* buf, size_t n) {
- s->append(buf, n);
- }
-
- static string* StartRepeatedString(proto2::RepeatedPtrField<string>* r,
- size_t size_hint) {
- string* str = r->Add();
- // reserve() here appears to hurt performance rather than help.
- return str;
- }
-
- // Out-of-line string ////////////////////////////////////////////////////////
-
- static void SetOutOfLineStringHandlers(
- const proto2::FieldDescriptor* proto2_f, const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- // This type is only used for non-repeated string fields.
- UPB_ASSERT(!f->IsSequence());
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartOutOfLineString, new FieldOffset(proto2_f, r))));
- CHKRET(h->SetStringHandler(f, UpbMakeHandler(OnStringBuf)));
- }
-
- static string* StartOutOfLineString(proto2::Message* m,
- const FieldOffset* info,
- size_t size_hint) {
- info->SetHasbit(m);
- string** str = info->GetFieldPointer<string*>(m);
- if (*str == &::proto2::internal::GetEmptyString())
- *str = new string();
- (*str)->clear();
- // reserve() here appears to hurt performance rather than help.
- return *str;
- }
-
- // Cord //////////////////////////////////////////////////////////////////////
-
- static void SetCordHandlers(const proto2::FieldDescriptor* proto2_f,
- const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- if (f->IsSequence()) {
- SetStartRepeatedField<Cord>(proto2_f, r, f, h);
- CHKRET(h->SetStartStringHandler(f, UpbMakeHandler(StartRepeatedCord)));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartCord, new FieldOffset(proto2_f, r))));
- }
- CHKRET(h->SetStringHandler(f, UpbMakeHandler(OnCordBuf)));
- }
-
- static Cord* StartCord(proto2::Message* m, const FieldOffset* offset,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- offset->SetHasbit(m);
- Cord* field = offset->GetFieldPointer<Cord>(m);
- field->Clear();
- return field;
- }
-
- static void OnCordBuf(Cord* c, const char* buf, size_t n) {
- c->Append(StringPiece(buf, n));
- }
-
- static Cord* StartRepeatedCord(proto2::RepeatedField<Cord>* r,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- return r->Add();
- }
-
- // SubMessage ////////////////////////////////////////////////////////////////
-
- class SubMessageHandlerData : public FieldOffset {
- public:
- SubMessageHandlerData(const proto2::Message& prototype,
- const proto2::FieldDescriptor* f,
- const _pi::Proto2Reflection* r)
- : FieldOffset(f, r) {
- prototype_ = GetWeakPrototype(prototype, f);
- if (!prototype_) prototype_ = GetFieldPrototype(prototype, f);
- }
-
- const proto2::Message* prototype() const { return prototype_; }
-
- private:
- const proto2::Message* prototype_;
- };
-
- static void SetRequiredMessageHandlers(
- const proto2::FieldDescriptor* proto2_f, const proto2::Message& m,
- const _pi::Proto2Reflection* r, const upb::FieldDef* f,
- upb::Handlers* h) {
- if (f->IsSequence()) {
- SetStartRepeatedSubmessageField(proto2_f, r, f, h);
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRepeatedSubMessage,
- new SubMessageHandlerData(m, proto2_f, r))));
- } else {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRequiredSubMessage, new FieldOffset(proto2_f, r))));
- }
- }
-
- static proto2::Message* StartRequiredSubMessage(proto2::Message* m,
- const FieldOffset* offset) {
- offset->SetHasbit(m);
- return offset->GetFieldPointer<proto2::Message>(m);
- }
-
- static void SetMessageHandlers(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& m,
- const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- std::unique_ptr<SubMessageHandlerData> data(
- new SubMessageHandlerData(m, proto2_f, r));
- if (f->IsSequence()) {
- SetStartRepeatedSubmessageField(proto2_f, r, f, h);
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRepeatedSubMessage, data.release())));
- } else {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartSubMessage, data.release())));
- }
- }
-
- static void SetWeakMessageHandlers(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& m,
- const _pi::Proto2Reflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- std::unique_ptr<SubMessageHandlerData> data(
- new SubMessageHandlerData(m, proto2_f, r));
- if (f->IsSequence()) {
- SetStartRepeatedSubmessageField(proto2_f, r, f, h);
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRepeatedSubMessage, data.release())));
- } else {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartWeakSubMessage, data.release())));
- }
- }
-
- static void* StartSubMessage(proto2::Message* m,
- const SubMessageHandlerData* info) {
- info->SetHasbit(m);
- proto2::Message** subm = info->GetFieldPointer<proto2::Message*>(m);
- if (*subm == info->prototype()) *subm = (*subm)->New();
- return *subm;
- }
-
- static void* StartWeakSubMessage(proto2::Message* m,
- const SubMessageHandlerData* info) {
- info->SetHasbit(m);
- proto2::Message** subm = info->GetFieldPointer<proto2::Message*>(m);
- if (*subm == NULL) {
- *subm = info->prototype()->New();
- }
- return *subm;
- }
-
- 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);
- UPB_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);
- UPB_ASSERT(false);
- }
- static void Merge(const Type& from, Type* to) {
- to->MergeFrom(from);
- }
-#endif
- };
-
- // Closure is a RepeatedPtrField<SubMessageType>*, but we access it through
- // its base class RepeatedPtrFieldBase*.
- static proto2::Message* StartRepeatedSubMessage(
- proto2::internal::RepeatedPtrFieldBase* r,
- const SubMessageHandlerData* info) {
- proto2::Message* submsg = r->AddFromCleared<RepeatedMessageTypeHandler>();
- if (!submsg) {
- submsg = info->prototype()->New();
- r->AddAllocated<RepeatedMessageTypeHandler>(submsg);
- }
- return submsg;
- }
-};
-
-bool TrySetProto1WriteHandlers(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& m,
- const upb::FieldDef* upb_f, upb::Handlers* h) {
- return googlepb::P2R_Handlers::TrySet(proto2_f, m, upb_f, h);
-}
-
-const proto2::Message* GetProto1FieldPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f) {
- const proto2::Message *weak = googlepb::P2R_Handlers::GetWeakPrototype(m, f);
- if (weak) return weak;
- if (f->cpp_type() != proto2::FieldDescriptor::CPPTYPE_MESSAGE) {
- return NULL;
- }
- return googlepb::P2R_Handlers::GetFieldPrototype(m, f);
-}
-
-} // namespace googlepb
-} // namespace upb
diff --git a/upb/bindings/googlepb/proto1.int.h b/upb/bindings/googlepb/proto1.int.h
deleted file mode 100644
index d5c9cad..0000000
--- a/upb/bindings/googlepb/proto1.int.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Support for registering field handlers that can write into a legacy proto1
-// message. This functionality is only needed inside Google.
-//
-// This is an internal-only interface.
-
-#ifndef UPB_GOOGLE_PROTO1_H_
-#define UPB_GOOGLE_PROTO1_H_
-
-namespace proto2 {
-class FieldDescriptor;
-class Message;
-}
-
-namespace upb {
-class FieldDef;
-class Handlers;
-}
-
-namespace upb {
-namespace googlepb {
-
-// Sets field handlers in the given Handlers object for writing to a single
-// field (as described by "proto2_f" and "upb_f") into a message constructed
-// by the same factory as "prototype." Returns true if this was successful
-// (this will fail if "prototype" is not a proto1 message, or if we can't
-// handle it for some reason).
-bool TrySetProto1WriteHandlers(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& prototype,
- const upb::FieldDef* upb_f, upb::Handlers* h);
-
-// Returns a prototype for the given this (possibly-weak) field. Returns NULL
-// if this is not a submessage field of any kind (weak or no).
-const proto2::Message* GetProto1FieldPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f);
-
-} // namespace googlepb
-} // namespace upb
-
-#endif // UPB_GOOGLE_PROTO1_H_
diff --git a/upb/bindings/googlepb/proto2.cc b/upb/bindings/googlepb/proto2.cc
deleted file mode 100644
index ebfedca..0000000
--- a/upb/bindings/googlepb/proto2.cc
+++ /dev/null
@@ -1,1395 +0,0 @@
-//
-// Note that we have received an exception from c-style-artiters regarding
-// dynamic_cast<> in this file:
-// https://groups.google.com/a/google.com/d/msg/c-style/7Zp_XCX0e7s/I6dpzno4l-MJ
-//
-// IMPORTANT NOTE! This file is compiled TWICE, once with UPB_GOOGLE3 defined
-// and once without! This allows us to provide functionality against proto2
-// and protobuf opensource both in a single binary without the two conflicting.
-// However we must be careful not to violate the ODR.
-
-#include "upb/bindings/googlepb/proto2.int.h"
-
-#include <map>
-
-#include "upb/bindings/googlepb/proto1.int.h"
-#include "upb/def.h"
-#include "upb/handlers.h"
-#include "upb/msg.h"
-#include "upb/sink.h"
-
-namespace {
-
-template<typename To, typename From> To CheckDownCast(From* f) {
- UPB_ASSERT(f == NULL || dynamic_cast<To>(f) != NULL);
- return static_cast<To>(f);
-}
-
-}
-
-// Unconditionally evaluate, but also assert in debug mode.
-#define CHKRET(x) do { bool ok = (x); UPB_ASSERT(ok); } while (0)
-
-namespace upb {
-namespace google_google3 { class GMR_Handlers; }
-namespace google_opensource { class GMR_Handlers; }
-} // namespace upb
-
-// BEGIN DOUBLE COMPILATION TRICKERY. //////////////////////////////////////////
-
-#ifdef UPB_GOOGLE3
-
-// TODO(haberman): Add public functionality to ExtensionSet for populating
-// LazyFields.
-#define private public
-#include "net/proto2/public/extension_set.h"
-#undef private
-
-#include "net/proto2/proto/descriptor.pb.h"
-#include "net/proto2/public/descriptor.h"
-#include "net/proto2/public/generated_message_reflection.h"
-#include "net/proto2/public/lazy_field.h"
-#include "net/proto2/public/message.h"
-#include "net/proto2/public/repeated_field.h"
-#include "net/proto2/public/string_piece_field_support.h"
-
-namespace goog = ::proto2;
-namespace me = ::upb::google_google3;
-
-#else
-
-// TODO(haberman): remove these once new versions of protobuf that "friend"
-// upb are pervasive in the wild.
-#define protected public
-#include "google/protobuf/repeated_field.h"
-#undef protected
-
-#define private public
-#include "google/protobuf/generated_message_reflection.h"
-#undef private
-
-#define private public
-#include "google/protobuf/extension_set.h"
-#undef private
-
-#include "google/protobuf/descriptor.h"
-#include "google/protobuf/descriptor.pb.h"
-#include "google/protobuf/message.h"
-
-namespace goog = ::google::protobuf;
-namespace me = ::upb::google_opensource;
-
-using goog::int32;
-using goog::int64;
-using goog::uint32;
-using goog::uint64;
-using goog::scoped_ptr;
-
-#endif // ifdef UPB_GOOGLE3
-
-// END DOUBLE COMPILATION TRICKERY. ////////////////////////////////////////////
-
-// Have to define this manually since older versions of proto2 didn't define
-// an enum value for STRING.
-#define UPB_CTYPE_STRING 0
-
-template <class T> static T* GetPointer(void* message, size_t offset) {
- return reinterpret_cast<T*>(static_cast<char*>(message) + offset);
-}
-template <class T>
-static const T* GetConstPointer(const void* message, size_t offset) {
- return reinterpret_cast<const T*>(static_cast<const char*>(message) + offset);
-}
-
-// This class contains handlers that can write into a proto2 class whose
-// reflection class is GeneratedMessageReflection. (Despite the name, even
-// DynamicMessage uses GeneratedMessageReflection, so this covers all proto2
-// messages generated by the compiler.) To do this it must break the
-// encapsulation of GeneratedMessageReflection and therefore depends on
-// internal interfaces that are not guaranteed to be stable. This class will
-// need to be updated if any non-backward-compatible changes are made to
-// GeneratedMessageReflection.
-class me::GMR_Handlers {
- public:
- // Returns true if we were able to set an accessor and any other properties
- // of the FieldDef that are necessary to read/write this field to a
- // proto2::Message.
- static bool TrySet(const goog::FieldDescriptor* proto2_f,
- const goog::Message& m, const upb::FieldDef* upb_f,
- upb::Handlers* h) {
- const goog::Reflection* base_r = m.GetReflection();
- // See file comment re: dynamic_cast.
- const goog::internal::GeneratedMessageReflection* r =
- dynamic_cast<const goog::internal::GeneratedMessageReflection*>(base_r);
- if (!r) return false;
-
-#define PRIMITIVE_TYPE(cpptype, cident) \
-case goog::FieldDescriptor::cpptype: \
- SetPrimitiveHandlers<cident>(proto2_f, r, upb_f, h); \
- return true;
-
- switch (proto2_f->cpp_type()) {
- PRIMITIVE_TYPE(CPPTYPE_INT32, int32);
- PRIMITIVE_TYPE(CPPTYPE_INT64, int64);
- PRIMITIVE_TYPE(CPPTYPE_UINT32, uint32);
- PRIMITIVE_TYPE(CPPTYPE_UINT64, uint64);
- PRIMITIVE_TYPE(CPPTYPE_DOUBLE, double);
- PRIMITIVE_TYPE(CPPTYPE_FLOAT, float);
- PRIMITIVE_TYPE(CPPTYPE_BOOL, bool);
- case goog::FieldDescriptor::CPPTYPE_ENUM:
- if (proto2_f->is_extension()) {
- SetEnumExtensionHandlers(proto2_f, r, upb_f, h);
- } else {
- SetEnumHandlers(proto2_f, r, upb_f, h);
- }
- return true;
- case goog::FieldDescriptor::CPPTYPE_STRING: {
- if (proto2_f->is_extension()) {
-#ifdef UPB_GOOGLE3
- SetStringExtensionHandlers<string>(proto2_f, r, upb_f, h);
-#else
- SetStringExtensionHandlers<std::string>(proto2_f, r, upb_f, h);
-#endif
- return true;
- }
-
- // Old versions of the open-source protobuf release erroneously default
- // to Cord even though that has never been supported in the open-source
- // release.
- int32_t ctype = proto2_f->options().has_ctype() ?
- proto2_f->options().ctype()
- : UPB_CTYPE_STRING;
- switch (ctype) {
-#ifdef UPB_GOOGLE3
- case goog::FieldOptions::STRING:
- SetStringHandlers<string>(proto2_f, r, upb_f, h);
- return true;
- case goog::FieldOptions::CORD:
- SetCordHandlers(proto2_f, r, upb_f, h);
- return true;
- case goog::FieldOptions::STRING_PIECE:
- SetStringPieceHandlers(proto2_f, r, upb_f, h);
- return true;
-#else
- case UPB_CTYPE_STRING:
- SetStringHandlers<std::string>(proto2_f, r, upb_f, h);
- return true;
-#endif
- default:
- return false;
- }
- }
- case goog::FieldDescriptor::CPPTYPE_MESSAGE:
-#ifdef UPB_GOOGLE3
- if (proto2_f->options().lazy() &&
- // proto2 lets you set lazy=true on a repeated field, but doesn't
- // actually support lazy repeated messages, so just ignore
- // lazy=true for repeated messages.
- !proto2_f->is_repeated()) {
- // Supports lazy fields and lazy extensions.
- SetLazyFieldHandlers(proto2_f, m, r, upb_f, h);
- return true;
- }
-#endif
- if (proto2_f->is_extension()) {
- SetSubMessageExtensionHandlers(proto2_f, m, r, upb_f, h);
- return true;
- }
- SetSubMessageHandlers(proto2_f, m, r, upb_f, h);
- return true;
- default:
- return false;
- }
- }
-
-#undef PRIMITIVE_TYPE
-
- static const goog::Message* GetFieldPrototype(
- const goog::Message& m, const goog::FieldDescriptor* f) {
- // We assume that all submessages (and extensions) will be constructed
- // using the same MessageFactory as this message. This doesn't cover the
- // case of CodedInputStream::SetExtensionRegistry().
- // See file comment re: dynamic_cast.
- const goog::internal::GeneratedMessageReflection* r =
- dynamic_cast<const goog::internal::GeneratedMessageReflection*>(
- m.GetReflection());
- if (!r) return NULL;
- return r->message_factory_->GetPrototype(f->message_type());
- }
-
- private:
- static upb_selector_t GetSelector(const upb::FieldDef* f,
- upb::Handlers::Type type) {
- upb::Handlers::Selector selector;
- bool ok = upb::Handlers::GetSelector(f, type, &selector);
- UPB_ASSERT(ok);
- return selector;
- }
-
- static int64_t GetHasbit(
- const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r) {
- // proto2 does not store hasbits for repeated fields.
- UPB_ASSERT(!f->is_repeated());
- return (r->has_bits_offset_ * 8) + f->index();
- }
-
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- static size_t GetOneofDiscriminantOffset(
- const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r) {
- UPB_ASSERT(f->containing_oneof());
- return r->oneof_case_offset_ + f->containing_oneof()->index();
- }
-#endif
-
- static uint16_t GetOffset(
- const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r) {
- int index = f->index();
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- if (f->containing_oneof()) {
- index =
- f->containing_type()->field_count() + f->containing_oneof()->index();
- }
-#endif
- return r->offsets_[index];
- }
-
- // 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)
- : FieldDataBase(r),
- offset_(GetOffset(f, r)), is_repeated_(f->is_repeated()) {
- if (!is_repeated_) {
- int64_t hasbit = GetHasbit(f, r);
- hasbyte_ = hasbit / 8;
- mask_ = 1 << (hasbit % 8);
- }
- }
-
- template <class T> T* GetFieldPointer(goog::Message* message) const {
- return GetPointer<T>(message, offset_);
- }
-
- void SetHasbit(void* m) const {
- UPB_ASSERT(!is_repeated_);
- uint8_t* byte = GetPointer<uint8_t>(m, hasbyte_);
- *byte |= mask_;
- }
-
- private:
- const size_t offset_;
- bool is_repeated_;
-
- // Only for non-repeated fields.
- int32_t hasbyte_;
- int8_t mask_;
- };
-
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- class OneofFieldData : public FieldDataBase {
- public:
- OneofFieldData(const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r)
- : FieldDataBase(r),
- field_number_offset_(GetOneofDiscriminantOffset(f, r)),
- field_number_(f->number()) {
- const goog::OneofDescriptor* oneof = f->containing_oneof();
-
- // Determine the type of each discriminant value, so we know what kind of
- // value to delete if we are changing the type.
- //
- // For example, we may find that the oneof has three possible values: an
- // int32, a message, and a string. For the int32 there is nothing to
- // delete, but the message and the string need to be deleted when we
- // switch to another oneof type, to avoid leaking it.
- //
- // TODO(haberman): share this map of types between all fields in the
- // oneof. Right now we duplicate it for each one, which is wasteful.
- for (int i = 0; i < oneof->field_count(); i++) {
- const goog::FieldDescriptor* oneof_f = oneof->field(i);
- OneofType& type = types_[oneof_f->number()];
-
- switch (oneof_f->cpp_type()) {
- case goog::FieldDescriptor::CPPTYPE_STRING:
- type = GetTypeForString(oneof_f);
- break;
- case goog::FieldDescriptor::CPPTYPE_MESSAGE:
-#ifdef UPB_GOOGLE3
- if (oneof_f->options().lazy()) {
- type = ONEOF_TYPE_LAZYFIELD;
- break;
- }
-#endif
- type = ONEOF_TYPE_MESSAGE;
- break;
-
- default:
- type = ONEOF_TYPE_NONE;
- break;
- }
- }
-
- // "0" indicates that the field is not set.
- types_[0] = ONEOF_TYPE_NONE;
- }
-
- int32_t* GetFieldPointer(goog::Message* message) const {
- 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.
- bool SetOneofHas(goog::Message* m, const FieldOffset* ofs) const {
- int32_t *field_number = GetFieldPointer(m);
- if (*field_number == field_number_) {
- return false;
- } else {
- ClearOneof(m, ofs, *field_number);
- *field_number = field_number_;
- return true;
- }
- }
-
- private:
- enum OneofType {
- ONEOF_TYPE_NONE,
- ONEOF_TYPE_STRING,
- ONEOF_TYPE_MESSAGE
-#ifdef UPB_GOOGLE3
- ,
- ONEOF_TYPE_GLOBALSTRING,
- ONEOF_TYPE_CORD,
- ONEOF_TYPE_STRINGPIECE,
- ONEOF_TYPE_LAZYFIELD
-#endif
- };
-
- OneofType GetTypeForString(const goog::FieldDescriptor* f) {
- switch (f->options().ctype()) {
- case goog::FieldOptions::STRING:
-#ifdef UPB_GOOGLE3
- return ONEOF_TYPE_GLOBALSTRING;
-#else
- return ONEOF_TYPE_STRING;
-#endif
-
-#ifdef UPB_GOOGLE3
- case goog::FieldOptions::CORD:
- return ONEOF_TYPE_CORD;
- case goog::FieldOptions::STRING_PIECE:
- return ONEOF_TYPE_STRINGPIECE;
-#endif
- default:
- UPB_ASSERT(false);
- return ONEOF_TYPE_NONE;
- }
- }
-
- // Offset of the uint32 that specifies which field is set.
- size_t field_number_offset_;
-
- // Field number for this field.
- int32_t field_number_;
-
- // The types of the oneof fields, indexed by field_number_.
- std::map<int32_t, OneofType> types_;
- };
-
- class OneofFieldHandlerData : public FieldOffset {
- public:
- OneofFieldHandlerData(const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r)
- : FieldOffset(f, r),
- oneof_data_(f, r) {}
-
- bool SetOneofHas(goog::Message* message) const {
- return oneof_data_.SetOneofHas(message, this);
- }
-
- public:
- OneofFieldData oneof_data_;
- };
-#endif // GOOGLE_PROTOBUF_HAS_ONEOF
-
- class ExtensionFieldData {
- public:
- ExtensionFieldData(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r)
- : offset_(r->extensions_offset_),
- field_descriptor_(proto2_f) {
- }
-
- int number() const { return field_descriptor_->number(); }
- goog::internal::FieldType type() const { return field_descriptor_->type(); }
- const goog::FieldDescriptor* field_descriptor() const {
- return field_descriptor_;
- }
-
- goog::internal::ExtensionSet* GetExtensionSet(goog::Message* m) const {
- return GetPointer<goog::internal::ExtensionSet>(m, offset_);
- }
-
- private:
- const size_t offset_;
- // We know it will outlive because we require that the input message used to
- // build these handlers outlives us, and the descriptor will outlive the
- // message.
- const goog::FieldDescriptor* field_descriptor_;
- };
-
- // StartSequence /////////////////////////////////////////////////////////////
-
- template <class T>
- static void SetStartRepeatedField(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBindT(&PushOffset<goog::RepeatedField<T> >,
- new FieldOffset(proto2_f, r))));
- }
-
- template <class T>
- static void SetStartRepeatedPtrField(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBindT(&PushOffset<goog::RepeatedPtrField<T> >,
- new FieldOffset(proto2_f, r))));
- }
-
- static void SetStartRepeatedSubmessageField(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- CHKRET(h->SetStartSequenceHandler(
- f, UpbBind(&PushOffset<goog::internal::RepeatedPtrFieldBase>,
- new FieldOffset(proto2_f, r))));
- }
-
- template <class T>
- static T* PushOffset(goog::Message* message, const FieldOffset* offset) {
- return offset->GetFieldPointer<T>(message);
- }
-
- // Primitive Value (numeric, bool) ///////////////////////////////////////////
-
- template <typename T> static void SetPrimitiveHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- if (proto2_f->is_extension()) {
- scoped_ptr<ExtensionFieldData> data(new ExtensionFieldData(proto2_f, r));
- if (f->IsSequence()) {
- CHKRET(h->SetValueHandler<T>(
- f, UpbBindT(AppendPrimitiveExtension<T>, data.release())));
- } else {
- CHKRET(h->SetValueHandler<T>(
- f, UpbBindT(SetPrimitiveExtension<T>, data.release())));
- }
- }
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- else if (proto2_f->containing_oneof()) {
- UPB_ASSERT(!proto2_f->is_repeated());
- CHKRET(h->SetValueHandler<T>(
- f, UpbBindT(SetOneofPrimitive<T>,
- new OneofFieldHandlerData(proto2_f, r))));
- }
-#endif
- else {
- if (f->IsSequence()) {
- SetStartRepeatedField<T>(proto2_f, r, f, h);
- CHKRET(h->SetValueHandler<T>(f, UpbMakeHandlerT(AppendPrimitive<T>)));
- } else {
- CHKRET(upb_msg_setscalarhandler(h, f, GetOffset(proto2_f, r),
- GetHasbit(proto2_f, r)));
- }
- }
- }
-
- template <typename T>
- static void AppendPrimitive(goog::RepeatedField<T>* r, T val) { r->Add(val); }
-
- template <typename T>
- static void AppendPrimitiveExtension(goog::Message* m,
- const ExtensionFieldData* data, T val) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- // TODO(haberman): give an accurate value for "packed"
- goog::internal::RepeatedPrimitiveTypeTraits<T>::Add(
- data->number(), data->type(), true, val, set);
- }
-
- template <typename T>
- static void SetPrimitiveExtension(goog::Message* m,
- const ExtensionFieldData* data, T val) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- goog::internal::PrimitiveTypeTraits<T>::Set(data->number(), data->type(),
- val, set);
- }
-
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- template <typename T>
- static void SetOneofPrimitive(goog::Message* m,
- const OneofFieldHandlerData* data, T val) {
- data->SetOneofHas(m);
- const FieldOffset* ofs = data;
- T* ptr = ofs->GetFieldPointer<T>(m);
- *ptr = val;
- }
-#endif
-
- // Enum //////////////////////////////////////////////////////////////////////
-
- class EnumHandlerData : public FieldOffset {
- public:
- EnumHandlerData(const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f)
- : FieldOffset(proto2_f, r),
- field_number_(f->number()),
- enum_(upb_downcast_enumdef(f->subdef())) {}
-
- bool IsValidValue(int32_t val) const {
- return enum_->FindValueByNumber(val) != NULL;
- }
-
- int32_t field_number() const { return field_number_; }
-
- private:
- int32_t field_number_;
- const upb::EnumDef* enum_;
- };
-
- static void SetEnumHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(!proto2_f->is_extension());
- scoped_ptr<EnumHandlerData> data(new EnumHandlerData(proto2_f, r, f));
- if (f->IsSequence()) {
- CHKRET(h->SetInt32Handler(f, UpbBind(AppendEnum, data.release())));
- } else {
- CHKRET(h->SetInt32Handler(f, UpbBind(SetEnum, data.release())));
- }
- }
-
- static void SetEnum(goog::Message* m, const EnumHandlerData* data,
- int32_t val) {
- if (data->IsValidValue(val)) {
- int32_t* message_val = data->GetFieldPointer<int32_t>(m);
- *message_val = val;
- data->SetHasbit(m);
- } else {
- data->GetUnknownFieldSet(m)->AddVarint(data->field_number(), val);
- }
- }
-
- static void AppendEnum(goog::Message* m, const EnumHandlerData* data,
- int32_t val) {
- // Closure is the enclosing message. We can't use the RepeatedField<> as
- // the closure because we need to go back to the message for unrecognized
- // enum values, which go into the unknown field set.
- if (data->IsValidValue(val)) {
- goog::RepeatedField<int32_t>* r =
- data->GetFieldPointer<goog::RepeatedField<int32_t> >(m);
- r->Add(val);
- } else {
- data->GetUnknownFieldSet(m)->AddVarint(data->field_number(), val);
- }
- }
-
- // EnumExtension /////////////////////////////////////////////////////////////
-
- static void SetEnumExtensionHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(proto2_f->is_extension());
- scoped_ptr<ExtensionFieldData> data(new ExtensionFieldData(proto2_f, r));
- if (f->IsSequence()) {
- CHKRET(
- h->SetInt32Handler(f, UpbBind(AppendEnumExtension, data.release())));
- } else {
- CHKRET(h->SetInt32Handler(f, UpbBind(SetEnumExtension, data.release())));
- }
- }
-
- static void SetEnumExtension(goog::Message* m, const ExtensionFieldData* data,
- int32_t val) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- set->SetEnum(data->number(), data->type(), val, NULL);
- }
-
- static void AppendEnumExtension(goog::Message* m,
- const ExtensionFieldData* data, int32_t val) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- // TODO(haberman): give an accurate value for "packed"
- set->AddEnum(data->number(), data->type(), true, val, NULL);
- }
-
- // String ////////////////////////////////////////////////////////////////////
-
- // For scalar (non-repeated) string fields.
- template <class T> class StringHandlerData : public FieldOffset {
- public:
- StringHandlerData(const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r)
- : FieldOffset(proto2_f, r),
- prototype_(*GetConstPointer<T*>(r->default_instance_,
- GetOffset(proto2_f, r))) {}
-
- const T* prototype() const { return prototype_; }
-
- T** GetStringPointer(goog::Message* message) const {
- return GetFieldPointer<T*>(message);
- }
-
- private:
- const T* prototype_;
- };
-
- template <typename T> static void SetStringHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f,
- upb::Handlers* h) {
- UPB_ASSERT(!proto2_f->is_extension());
- CHKRET(h->SetStringHandler(f, UpbMakeHandlerT(&OnStringBuf<T>)));
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- if (proto2_f->containing_oneof()) {
- UPB_ASSERT(!f->IsSequence());
- CHKRET(h->SetStartStringHandler(
- f, UpbBindT(&StartOneofString<T>,
- new OneofFieldHandlerData(proto2_f, r))));
- } else
-#endif
- if (f->IsSequence()) {
- SetStartRepeatedPtrField<T>(proto2_f, r, f, h);
- CHKRET(
- h->SetStartStringHandler(f, UpbMakeHandlerT(StartRepeatedString<T>)));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBindT(StartString<T>, new StringHandlerData<T>(proto2_f, r))));
- }
- }
-
- // This needs to be templated because google3 string is not std::string.
- template <typename T>
- static T* StartString(goog::Message* m, const StringHandlerData<T>* data,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- 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();
-#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;
- }
-
- template <typename T>
- static void OnStringBuf(T* str, const char* buf, size_t n) {
- str->append(buf, n);
- }
-
- template <typename T>
- static T* StartRepeatedString(goog::RepeatedPtrField<T>* r,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- T* str = r->Add();
- str->clear();
- // reserve() here appears to hurt performance rather than help.
- return str;
- }
-
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- template <typename T>
- static T* StartOneofString(goog::Message* m,
- const OneofFieldHandlerData* data,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- const FieldOffset* ofs = data;
- 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();
- }
- return *str;
- }
-#endif
-
- // StringExtension ///////////////////////////////////////////////////////////
-
- template <typename T>
- static void SetStringExtensionHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(proto2_f->is_extension());
- CHKRET(h->SetStringHandler(f, UpbMakeHandlerT(OnStringBuf<T>)));
- scoped_ptr<ExtensionFieldData> data(new ExtensionFieldData(proto2_f, r));
- if (f->IsSequence()) {
- CHKRET(h->SetStartStringHandler(
- f, UpbBindT(StartRepeatedStringExtension<T>, data.release())));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBindT(StartStringExtension<T>, data.release())));
- }
- }
-
- // Templated because google3 is not std::string.
- template <class T>
- static T* StartStringExtension(goog::Message* m,
- const ExtensionFieldData* data,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- return set->MutableString(data->number(), data->type(), NULL);
- }
-
- template <class T>
- static T* StartRepeatedStringExtension(goog::Message* m,
- const ExtensionFieldData* data,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- return set->AddString(data->number(), data->type(), NULL);
- }
-
- // SubMessage ////////////////////////////////////////////////////////////////
-
- class SubMessageHandlerData : public FieldOffset {
- public:
- SubMessageHandlerData(const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r,
- const goog::Message* prototype)
- : FieldOffset(f, r), prototype_(prototype) {}
-
- const goog::Message* prototype() const { return prototype_; }
-
- private:
- const goog::Message* const prototype_;
- };
-
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- class OneofSubMessageHandlerData : public SubMessageHandlerData {
- public:
- OneofSubMessageHandlerData(const goog::FieldDescriptor* f,
- const goog::internal::GeneratedMessageReflection* r,
- const goog::Message* prototype)
- : SubMessageHandlerData(f, r, prototype),
- oneof_data_(f, r) {}
-
- bool SetOneofHas(goog::Message* m) const {
- return oneof_data_.SetOneofHas(m, this);
- }
-
- private:
- OneofFieldData oneof_data_;
- };
-#endif
-
- static void SetSubMessageHandlers(
- const goog::FieldDescriptor* proto2_f, const goog::Message& m,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- const goog::Message* field_prototype = GetFieldPrototype(m, proto2_f);
- scoped_ptr<SubMessageHandlerData> data(
- new SubMessageHandlerData(proto2_f, r, field_prototype));
-#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
- if (proto2_f->containing_oneof()) {
- UPB_ASSERT(!f->IsSequence());
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartOneofSubMessage, new OneofSubMessageHandlerData(
- proto2_f, r, field_prototype))));
- } else
-#endif
- if (f->IsSequence()) {
- SetStartRepeatedSubmessageField(proto2_f, r, f, h);
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRepeatedSubMessage, data.release())));
- } else {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartSubMessage, data.release())));
- }
- }
-
- static goog::Message* StartSubMessage(goog::Message* m,
- const SubMessageHandlerData* data) {
- 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;
- }
-
- class RepeatedMessageTypeHandler {
- public:
- typedef goog::Message Type;
-#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
- static goog::Arena* GetArena(Type* t) {
- return t->GetArena();
- }
- static void* GetMaybeArenaPointer(Type* t) {
- return t->GetMaybeArenaPointer();
- }
- static inline Type* NewFromPrototype(
- const Type* prototype, goog::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);
- UPB_ASSERT(false);
- }
-#endif // ifdef GOOGLE_PROTOBUF_HAS_ARENAS
-
- static void Merge(const Type& from, Type* to) {
- to->MergeFrom(from);
- }
- };
-
- // 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) {
-#ifdef GOOGLE_PROTOBUF_HAS_ARENAS
- return r->Add<RepeatedMessageTypeHandler>(
- const_cast<goog::Message*>(data->prototype()));
-#else
- // This code path is required not because of arena-related API changes but
- // because the variant of Add<>() that takes a prototype object was added
- // only recently. Without the prototype, there's no way for Add<>() to
- // create a new submessage with out typehandler implementation because we
- // don't have New() (because we don't template-specialize our typehandler
- // class on concrete message types). So we have to implement the runtime
- // polymorphism externally (in this function) and then use AddAllocated to
- // insert the pointer.
- goog::Message* submsg = r->AddFromCleared<RepeatedMessageTypeHandler>();
- if (!submsg) {
- submsg = data->prototype()->New();
- r->AddAllocated<RepeatedMessageTypeHandler>(submsg);
- }
- return submsg;
-#endif
- }
-
-#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;
- }
-#endif
-
- // SubMessageExtension ///////////////////////////////////////////////////////
-
- class SubMessageExtensionHandlerData : public ExtensionFieldData {
- public:
- SubMessageExtensionHandlerData(
- const goog::FieldDescriptor* proto2_f,
- const goog::internal::GeneratedMessageReflection* r,
- const goog::Message* prototype)
- : ExtensionFieldData(proto2_f, r),
- prototype_(prototype) {
- }
-
- const goog::Message* prototype() const { return prototype_; }
-
- private:
- const goog::Message* const prototype_;
- };
-
- static void SetSubMessageExtensionHandlers(
- const goog::FieldDescriptor* proto2_f,
- const goog::Message& m,
- const goog::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f,
- upb::Handlers* h) {
- const goog::Message* field_prototype = GetFieldPrototype(m, proto2_f);
- scoped_ptr<SubMessageExtensionHandlerData> data(
- new SubMessageExtensionHandlerData(proto2_f, r, field_prototype));
- if (f->IsSequence()) {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartRepeatedSubMessageExtension, data.release())));
- } else {
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartSubMessageExtension, data.release())));
- }
- }
-
- static goog::Message* StartRepeatedSubMessageExtension(
- goog::Message* m, const SubMessageExtensionHandlerData* data) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- // Because we found this message via a descriptor, we know it has a
- // descriptor and is therefore a Message and not a MessageLite.
- // Alternatively we could just use goog::MessageLite everywhere to avoid
- // this, but since they are in fact goog::Messages, it seems most clear
- // to refer to them as such.
- return CheckDownCast<goog::Message*>(set->AddMessage(
- data->number(), data->type(), *data->prototype(), NULL));
- }
-
- static goog::Message* StartSubMessageExtension(
- goog::Message* m, const SubMessageExtensionHandlerData* data) {
- goog::internal::ExtensionSet* set = data->GetExtensionSet(m);
- // See comment above re: this down cast.
- return CheckDownCast<goog::Message*>(set->MutableMessage(
- data->number(), data->type(), *data->prototype(), NULL));
- }
-
- // TODO(haberman): handle Unknown Fields.
-
-#ifdef UPB_GOOGLE3
- // Handlers for types/features only included in internal proto2 release:
- // Cord, StringPiece, LazyField, and MessageSet.
- // TODO(haberman): MessageSet.
-
- // Cord //////////////////////////////////////////////////////////////////////
-
- static void AppendBufToCord(const char* buf, size_t n,
- const upb::BufferHandle* handle, Cord* c) {
- const Cord* source_cord = handle->GetAttachedObject<Cord>();
- if (source_cord) {
- // This TODO is copied from CordReader::CopyToCord():
- // "We could speed this up by using CordReader internals."
- Cord piece(*source_cord);
- piece.RemovePrefix(handle->object_offset() + (buf - handle->buffer()));
- UPB_ASSERT(piece.size() >= n);
- piece.RemoveSuffix(piece.size() - n);
-
- c->Append(piece);
- } else {
- c->Append(StringPiece(buf, n));
- }
- }
-
- static void SetCordHandlers(
- const proto2::FieldDescriptor* proto2_f,
- const proto2::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(!proto2_f->is_extension());
- CHKRET(h->SetStringHandler(f, UpbMakeHandler(&OnCordBuf)));
- if (f->IsSequence()) {
- SetStartRepeatedField<Cord>(proto2_f, r, f, h);
- CHKRET(h->SetStartStringHandler(f, UpbMakeHandler(StartRepeatedCord)));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartCord, new FieldOffset(proto2_f, r))));
- }
- }
-
- static Cord* StartCord(goog::Message* m, const FieldOffset* offset,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- offset->SetHasbit(m);
- Cord* field = offset->GetFieldPointer<Cord>(m);
- field->Clear();
- return field;
- }
-
- static void OnCordBuf(Cord* c, const char* buf, size_t n,
- const upb::BufferHandle* handle) {
- AppendBufToCord(buf, n, handle, c);
- }
-
- static Cord* StartRepeatedCord(proto2::RepeatedField<Cord>* r,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- return r->Add();
- }
-
- // StringPiece ///////////////////////////////////////////////////////////////
-
- static void SetStringPieceHandlers(
- const proto2::FieldDescriptor* proto2_f,
- const proto2::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(!proto2_f->is_extension());
- CHKRET(h->SetStringHandler(f, UpbMakeHandler(OnStringPieceBuf)));
- if (f->IsSequence()) {
- SetStartRepeatedPtrField<proto2::internal::StringPieceField>(proto2_f, r,
- f, h);
- CHKRET(h->SetStartStringHandler(
- f, UpbMakeHandler(StartRepeatedStringPiece)));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartStringPiece, new FieldOffset(proto2_f, r))));
- }
- }
-
- static void OnStringPieceBuf(proto2::internal::StringPieceField* field,
- const char* buf, size_t len) {
- // TODO(haberman): alias if possible and enabled on the input stream.
- // TODO(haberman): add a method to StringPieceField that lets us avoid
- // this copy/malloc/free.
- size_t new_len = field->size() + len;
- char* data = new char[new_len];
- memcpy(data, field->data(), field->size());
- memcpy(data + field->size(), buf, len);
- field->CopyFrom(StringPiece(data, new_len));
- delete[] data;
- }
-
- static proto2::internal::StringPieceField* StartStringPiece(
- goog::Message* m, const FieldOffset* offset, size_t size_hint) {
- UPB_UNUSED(size_hint);
- offset->SetHasbit(m);
- proto2::internal::StringPieceField* field =
- offset->GetFieldPointer<proto2::internal::StringPieceField>(m);
- field->Clear();
- return field;
- }
-
- static proto2::internal::StringPieceField* StartRepeatedStringPiece(
- proto2::RepeatedPtrField<proto2::internal::StringPieceField>* r,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- proto2::internal::StringPieceField* field = r->Add();
- field->Clear();
- return field;
- }
-
- // LazyField /////////////////////////////////////////////////////////////////
-
- // For lazy fields we set both lazy and eager handlers. The user can
- // configure the data source to call either, though lazy handlers may only be
- // used when the source data is binary protobuf.
- static void SetLazyFieldHandlers(
- const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& m,
- const proto2::internal::GeneratedMessageReflection* r,
- const upb::FieldDef* f, upb::Handlers* h) {
- UPB_ASSERT(!proto2_f->is_repeated());
- const goog::Message* field_prototype = GetFieldPrototype(m, proto2_f);
- CHKRET(h->SetStringHandler(f, UpbMakeHandler(OnLazyFieldBuf)));
- if (proto2_f->is_extension()) {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartLazyExtension, new ExtensionFieldData(proto2_f, r))));
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartSubMessageExtension,
- new SubMessageExtensionHandlerData(proto2_f, r,
- field_prototype))));
- } else {
- CHKRET(h->SetStartStringHandler(
- f, UpbBind(StartLazyField, new FieldOffset(proto2_f, r))));
- CHKRET(h->SetStartSubMessageHandler(
- f, UpbBind(StartLazyFieldEager,
- new SubMessageHandlerData(proto2_f, r, field_prototype))));
- }
- }
-
- static proto2::internal::LazyField* StartLazyField(proto2::Message* m,
- const FieldOffset* offset,
- size_t size_hint) {
- UPB_UNUSED(size_hint);
- offset->SetHasbit(m);
- proto2::internal::LazyField* field =
- offset->GetFieldPointer<proto2::internal::LazyField>(m);
- field->Clear();
- return field;
- }
-
- // For when the field has a lazy representation but we parse it eagerly anyway
- // (either because we want to or because we're parsing from a format other
- // than binary protobuf).
- static proto2::Message* StartLazyFieldEager(
- proto2::Message* m, const SubMessageHandlerData* data) {
- data->SetHasbit(m);
- proto2::internal::LazyField* field =
- data->GetFieldPointer<proto2::internal::LazyField>(m);
- return field->MutableByPrototype(*data->prototype());
- }
-
- class LazyMessageExtensionImpl
- : public proto2::internal::ExtensionSet::LazyMessageExtension {
- public:
- 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 {
- return lazy_field_.GetByPrototype(
- static_cast<const proto2::Message&>(prototype));
- }
-
- virtual proto2::MessageLite* MutableMessage(
- const proto2::MessageLite& prototype) {
- return lazy_field_.MutableByPrototype(
- static_cast<const proto2::Message&>(prototype));
- }
-
- virtual void SetAllocatedMessage(proto2::MessageLite* message) {
- return lazy_field_.SetAllocated(static_cast<proto2::Message*>(message));
- }
-
- virtual void UnsafeArenaSetAllocatedMessage(proto2::MessageLite* message) {
- return lazy_field_.UnsafeArenaSetAllocated(
- static_cast<proto2::Message*>(message));
- }
-
- virtual proto2::MessageLite* ReleaseMessage(
- const proto2::MessageLite& prototype) {
- return lazy_field_.ReleaseByPrototype(
- 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(); }
-
- int SpaceUsed() const {
- return sizeof(*this) + lazy_field_.SpaceUsedExcludingSelf();
- }
-
- virtual void MergeFrom(const LazyMessageExtension& other) {
- MergeFrom(*static_cast<const LazyMessageExtensionImpl*>(&other));
- }
-
- virtual void MergeFrom(const LazyMessageExtensionImpl& other) {
- lazy_field_.MergeFrom(other.lazy_field_);
- }
-
- virtual void Clear() { lazy_field_.Clear(); }
-
- virtual bool ReadMessage(const proto2::MessageLite& prototype,
- proto2::io::CodedInputStream* input) {
- return lazy_field_.Read(input);
- }
-
- virtual void WriteMessage(int number,
- proto2::io::CodedOutputStream* output) const {
- lazy_field_.Write(number, output);
- }
-
- virtual uint8* WriteMessageToArray(int number, uint8* target) const {
- return lazy_field_.WriteToArray(number, target);
- }
-
- proto2::internal::LazyField& lazy_field() { return lazy_field_; }
-
- private:
- proto2::internal::LazyField lazy_field_;
- DISALLOW_COPY_AND_ASSIGN(LazyMessageExtensionImpl);
- };
-
- static proto2::internal::LazyField* StartLazyExtension(
- proto2::Message* m, const ExtensionFieldData* data, size_t size_hint) {
- proto2::internal::ExtensionSet* set = data->GetExtensionSet(m);
-
- // We have to break encapsulation here since no public accessors expose the
- // LazyField.
- //
- // TODO(haberman): add a function to ExtensionSet that allows us to set the
- // lazy field directly.
- proto2::internal::ExtensionSet::Extension* item;
- 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;
- item->lazymessage_value = lazy_extension;
- } else {
- lazy_extension =
- CheckDownCast<LazyMessageExtensionImpl*>(item->lazymessage_value);
- }
-
- item->is_cleared = false;
-
- return &lazy_extension->lazy_field();
- }
-
- static void OnLazyFieldBuf(proto2::internal::LazyField* field,
- const char* buf, size_t len,
- const upb::BufferHandle* handle) {
- Cord encoded(field->GetEncoded());
- AppendBufToCord(buf, len, handle, &encoded);
- field->SetEncoded(encoded);
- }
-
-#endif // UPB_GOOGLE3
-};
-
-namespace upb {
-namespace googlepb {
-
-bool TrySetWriteHandlers(const goog::FieldDescriptor* proto2_f,
- const goog::Message& prototype,
- const upb::FieldDef* upb_f, upb::Handlers* h) {
- return me::GMR_Handlers::TrySet(proto2_f, prototype, upb_f, h);
-}
-
-const goog::Message* GetProto2FieldPrototype(const goog::Message& m,
- const goog::FieldDescriptor* f) {
- if (f->cpp_type() != goog::FieldDescriptor::CPPTYPE_MESSAGE) {
- return NULL;
- }
- return me::GMR_Handlers::GetFieldPrototype(m, f);
-}
-
-} // namespace googlepb
-} // namespace upb
diff --git a/upb/bindings/googlepb/proto2.int.h b/upb/bindings/googlepb/proto2.int.h
deleted file mode 100644
index 4f45efb..0000000
--- a/upb/bindings/googlepb/proto2.int.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Support for registering field handlers that can write into a proto2
-// message that uses GeneratedMessageReflection (which includes all messages
-// generated by the proto2 compiler as well as DynamicMessage).
-//
-// This is an internal-only interface.
-
-#ifndef UPB_GOOGLE_PROTO2_H_
-#define UPB_GOOGLE_PROTO2_H_
-
-namespace proto2 {
-class FieldDescriptor;
-class Message;
-}
-
-namespace google {
-namespace protobuf {
-class FieldDescriptor;
-class Message;
-}
-}
-
-namespace upb {
-class FieldDef;
-class Handlers;
-}
-
-namespace upb {
-namespace googlepb {
-
-// Sets field handlers in the given Handlers object for writing to a single
-// field (as described by "proto2_f" and "upb_f") into a message constructed
-// by the same factory as "prototype." Returns true if this was successful
-// (this will fail if "prototype" is not a proto1 message, or if we can't
-// handle it for some reason).
-bool TrySetWriteHandlers(const proto2::FieldDescriptor* proto2_f,
- const proto2::Message& prototype,
- const upb::FieldDef* upb_f, upb::Handlers* h);
-bool TrySetWriteHandlers(const ::google::protobuf::FieldDescriptor* proto2_f,
- const ::google::protobuf::Message& prototype,
- const upb::FieldDef* upb_f, upb::Handlers* h);
-
-// Returns a prototype for the given field in "m", if the given message uses
-// GeneratedMessageReflection. Otherwise returns NULL.
-const proto2::Message* GetProto2FieldPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f);
-const ::google::protobuf::Message* GetProto2FieldPrototype(
- const ::google::protobuf::Message& m,
- const ::google::protobuf::FieldDescriptor* f);
-
-} // namespace googlepb
-} // namespace upb
-
-#endif // UPB_GOOGLE_PROTO2_H_
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback