summaryrefslogtreecommitdiff
path: root/upb/bindings
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2018-08-21 14:47:50 -0700
committerJosh Haberman <jhaberman@gmail.com>2018-08-21 14:47:50 -0700
commitc0a50de92300080a1cf11bf4ff0ec3b2d6240c10 (patch)
tree84736c4563940dd81aa5d2269e3ba638b5355edb /upb/bindings
parente3eae33fb5840dbec3c2bc9109fa164f6066baa8 (diff)
Removed a bunch of obsolete code.
A lot of this code was experimental or temporarily useful, but is no longer needed.
Diffstat (limited to 'upb/bindings')
-rw-r--r--upb/bindings/README22
-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
-rw-r--r--upb/bindings/linux/Makefile20
-rw-r--r--upb/bindings/linux/assert.h14
-rw-r--r--upb/bindings/linux/errno.h2
-rw-r--r--upb/bindings/linux/stdint.h2
-rw-r--r--upb/bindings/linux/stdio.h2
-rw-r--r--upb/bindings/linux/stdlib.h17
-rw-r--r--upb/bindings/linux/string.h7
-rw-r--r--upb/bindings/python/setup.py14
-rw-r--r--upb/bindings/python/test.py72
-rw-r--r--upb/bindings/python/upb.c732
-rw-r--r--upb/bindings/python/upb/__init__.py0
-rw-r--r--upb/bindings/ruby/README.md30
-rw-r--r--upb/bindings/ruby/extconf.rb13
-rw-r--r--upb/bindings/ruby/upb.c1173
-rw-r--r--upb/bindings/stdc++/string.h64
-rw-r--r--upb/bindings/stdc/error.c38
-rw-r--r--upb/bindings/stdc/error.h18
-rw-r--r--upb/bindings/stdc/io.c172
-rw-r--r--upb/bindings/stdc/io.h64
27 files changed, 1 insertions, 5030 deletions
diff --git a/upb/bindings/README b/upb/bindings/README
index e4bf0b8..3e176c9 100644
--- a/upb/bindings/README
+++ b/upb/bindings/README
@@ -1,25 +1,5 @@
This directory contains code that interfaces upb with external C/C++
-libraries. For example:
-
- * upb/bindings/{stdc,stdc++}
- interfaces between upb and the standard libraries of C and C++ (like C's
- FILE/stdio, C++'s string/iostream, etc.)
-
- * upb/bindings/googlepb
- interfaces between upb and the "protobuf" library distributed by Google.
+libraries. Right now this is:
* upb/bindings/lua:
a Lua extension that exposes upb to Lua programs via the Lua C API.
-
- * upb/bindings/linux:
- code and build system for building upb as a Linux kernel module.
-
-The two key characteristics that decide whether code belongs in upb/bindings/
-are:
-
- * Does the code's public API refer to types from another library?
- If so it belongs in upb/bindings/. But this doesn't include code that just
- happens to use another library internally, as an implementation detail.
-
- * Would this code be useful to someone who is not using this external library
- in some other way? If so, the code probably doesn't belong in upb/bindings/.
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_
diff --git a/upb/bindings/linux/Makefile b/upb/bindings/linux/Makefile
deleted file mode 100644
index 1736b61..0000000
--- a/upb/bindings/linux/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-obj-m = upb.o
-
-upb-objs = \
- ../../upb/upb.o \
- ../../upb/bytestream.o \
- ../../upb/def.o \
- ../../upb/handlers.o \
- ../../upb/table.o \
- ../../upb/refcount.o \
- ../../upb/msg.o \
-
-KVERSION = $(shell uname -r)
-
-ccflags-y := -I$(PWD) -I$(PWD)/../.. -Wno-declaration-after-statement -std=gnu99
-
-all:
- make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
-
-clean:
- make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
diff --git a/upb/bindings/linux/assert.h b/upb/bindings/linux/assert.h
deleted file mode 100644
index 543f7fb..0000000
--- a/upb/bindings/linux/assert.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include <linux/kernel.h>
-
-#ifndef UPB_LINUX_ASSERT_H
-#define UPB_LINUX_ASSERT_H
-
-#ifdef NDEBUG
-#define assert(x)
-#else
-#define assert(x) \
- if (!(x)) panic("Assertion failed: %s at %s:%d", #x, __FILE__, __LINE__);
-#endif
-
-#endif
diff --git a/upb/bindings/linux/errno.h b/upb/bindings/linux/errno.h
deleted file mode 100644
index d6c56bc..0000000
--- a/upb/bindings/linux/errno.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include <linux/errno.h>
diff --git a/upb/bindings/linux/stdint.h b/upb/bindings/linux/stdint.h
deleted file mode 100644
index 2aa5144..0000000
--- a/upb/bindings/linux/stdint.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include <linux/types.h>
diff --git a/upb/bindings/linux/stdio.h b/upb/bindings/linux/stdio.h
deleted file mode 100644
index dd22e5b..0000000
--- a/upb/bindings/linux/stdio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include <linux/kernel.h> // For sprintf and friends.
diff --git a/upb/bindings/linux/stdlib.h b/upb/bindings/linux/stdlib.h
deleted file mode 100644
index 5ae6742..0000000
--- a/upb/bindings/linux/stdlib.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
-** Linux-kernel implementations of some stdlib.h functions.
-*/
-
-#include <linux/slab.h>
-
-#ifndef UPB_LINUX_STDLIB_H
-#define UPB_LINUX_STDLIB_H
-
-static inline void *malloc(size_t size) { return kmalloc(size, GFP_ATOMIC); }
-static inline void free(void *p) { kfree(p); }
-
-static inline void *realloc(void *p, size_t size) {
- return krealloc(p, size, GFP_ATOMIC);
-}
-
-#endif
diff --git a/upb/bindings/linux/string.h b/upb/bindings/linux/string.h
deleted file mode 100644
index 9cfd9b3..0000000
--- a/upb/bindings/linux/string.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#ifndef UPB_LINUX_STRING_H_
-#define UPB_LINUX_STRING_H_
-
-#include <linux/string.h>
-
-#endif /* UPB_DEF_H_ */
diff --git a/upb/bindings/python/setup.py b/upb/bindings/python/setup.py
deleted file mode 100644
index 8abaff8..0000000
--- a/upb/bindings/python/setup.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from distutils.core import setup, Extension
-
-setup(name='upb',
- version='0.1',
- ext_modules=[
- Extension('upb.__init__', ['upb.c'],
- include_dirs=['../../'],
- define_macros=[("UPB_UNALIGNED_READS_OK", 1)],
- library_dirs=['../../upb'],
- libraries=['upb_pic'],
- ),
- ],
- packages=['upb']
- )
diff --git a/upb/bindings/python/test.py b/upb/bindings/python/test.py
deleted file mode 100644
index 29a6c45..0000000
--- a/upb/bindings/python/test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-
-import upb
-import unittest
-
-class TestFieldDef(unittest.TestCase):
- def test_construction(self):
- fielddef1 = upb.FieldDef()
- self.assertTrue(fielddef1.number is None)
- self.assertTrue(fielddef1.name is None)
- self.assertTrue(fielddef1.type is None)
- self.assertEqual(fielddef1.label, upb.LABEL_OPTIONAL)
-
- fielddef2 = upb.FieldDef(number=5, name="field2",
- label=upb.LABEL_REQUIRED, type=upb.TYPE_INT32,
- type_name="MyType")
-
- self.assertTrue(id(fielddef1) != id(fielddef2))
- self.assertEqual(fielddef2.number, 5)
- self.assertEqual(fielddef2.name, "field2")
- self.assertEqual(fielddef2.label, upb.LABEL_REQUIRED)
- self.assertEqual(fielddef2.type, upb.TYPE_INT32)
- self.assertEqual(fielddef2.type_name, "MyType")
-
- fielddef2.number = 8
- self.assertEqual(fielddef2.number, 8)
-
- fielddef2.name = "xxx"
- self.assertEqual(fielddef2.name, "xxx")
-
- fielddef2.label = upb.LABEL_REPEATED
- self.assertEqual(fielddef2.label, upb.LABEL_REPEATED)
-
- fielddef2.type = upb.TYPE_FLOAT
- self.assertEqual(fielddef2.type, upb.TYPE_FLOAT)
-
- def test_nosubclasses(self):
- def create_subclass():
- class MyClass(upb.FieldDef):
- pass
-
- self.assertRaises(TypeError, create_subclass)
-
- # TODO: test that assigning invalid values is properly prevented.
-
-class TestMessageDef(unittest.TestCase):
- def test_construction(self):
- msgdef1 = upb.MessageDef()
- self.assertTrue(msgdef1.fqname is None)
- self.assertEqual(msgdef1.fields(), [])
-
- fields = [upb.FieldDef(number=1, name="field1", type=upb.TYPE_INT32)]
- msgdef2 = upb.MessageDef(fqname="Message2", fields=fields)
-
- self.assertEqual(set(msgdef2.fields()), set(fields))
-
- f2 = upb.FieldDef(number=2, name="field2", type=upb.TYPE_INT64)
- msgdef2.add_field(f2)
-
- fields.append(f2)
- self.assertEqual(set(msgdef2.fields()), set(fields))
-
-class TestSymbolTable(unittest.TestCase):
- def test_construction(self):
- s = upb.SymbolTable()
- self.assertEqual(s.defs(), []);
-
- s.add_def(upb.MessageDef(fqname="A"))
- self.assertTrue(s.lookup("A") is not None)
- self.assertTrue(s.lookup("A") is s.lookup("A"))
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/upb/bindings/python/upb.c b/upb/bindings/python/upb.c
deleted file mode 100644
index 1646acc..0000000
--- a/upb/bindings/python/upb.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
-** Python extension exposing the core of upb: definitions, handlers,
-** and a message type.
-**/
-
-#include <stddef.h>
-#include <Python.h>
-#include "upb/def.h"
-#include "upb/msg.h"
-
-static bool streql(const char *a, const char *b) { return strcmp(a, b) == 0; }
-
-PyObject *PyUpb_Error(const char *str) {
- PyErr_SetString(PyExc_TypeError, str);
- return NULL;
-}
-
-int PyUpb_ErrorInt(const char *str) {
- PyErr_SetString(PyExc_TypeError, str);
- return -1;
-}
-
-#define PyUpb_CheckStatus(status) \
- if (!upb_ok(status)) return PyUpb_Error((status)->str);
-
-static upb_accessor_vtbl *PyUpb_AccessorForField(upb_fielddef *f);
-
-
-/* Object cache ***************************************************************/
-
-// For objects that are just wrappers around a C object pointer, we keep a
-// cache mapping C pointer -> wrapper object. This allows us to consistently
-// vend the same Python object given the same C object. This prevents us from
-// creating too many Python objects unnecessarily. Just as importantly, it
-// provides the expected semantics:
-//
-// if field.subdef is field.subdef:
-// print "Sanity prevails."
-//
-// If we conjured up a new wrapper object every time, the above would not be
-// true.
-//
-// The cost is having to put all such objects in a table, but since this only
-// applies to schema-level objects (defs, handlers, etc) this seems acceptable.
-// We do *not* have to put all message objects in this table.
-//
-// We use weak refs so that the cache does not prevent the wrapper objects from
-// being collected. The table is stored as a static variable; to use
-// sub-interpreters this would need to change, but I believe that using
-// sub-interpreters is exceedingly rare in practice.
-
-typedef struct {
- PyObject_HEAD;
- void *obj;
- PyObject *weakreflist;
-} PyUpb_ObjWrapper;
-
-static PyObject *obj_cache = NULL;
-static PyObject *reverse_cache = NULL;
-static PyObject *weakref_callback = NULL;
-
-// Utility functions for manipulating Python dictionaries keyed by pointer.
-
-static PyObject *PyUpb_StringForPointer(const void *ptr) {
- PyObject *o = PyString_FromStringAndSize((const char *)&ptr, sizeof(void*));
- UPB_ASSERT(o);
- return o;
-}
-
-static PyObject *PyUpb_ObjCacheDeleteCallback(PyObject *self, PyObject *ref) {
- // Python very unfortunately clears the weakref before running our callback.
- // This prevents us from using the weakref to find the C pointer we need to
- // remove from the cache. As a result we are forced to keep a second map
- // mapping weakref->C pointer.
- PyObject *ptr_str = PyDict_GetItem(reverse_cache, ref);
- UPB_ASSERT(ptr_str);
- int err = PyDict_DelItem(obj_cache, ptr_str);
- UPB_ASSERT(!err);
- err = PyDict_DelItem(reverse_cache, ref);
- UPB_ASSERT(!err);
- return Py_None;
-}
-
-static PyObject *PyUpb_ObjCacheGet(const void *obj, PyTypeObject *type) {
- PyObject *kv = PyUpb_StringForPointer(obj);
- PyObject *ref = PyDict_GetItem(obj_cache, kv);
- PyObject *ret;
- if (ref) {
- ret = PyWeakref_GetObject(ref);
- UPB_ASSERT(ret != Py_None);
- Py_INCREF(ret);
- } else {
- PyUpb_ObjWrapper *wrapper = (PyUpb_ObjWrapper*)type->tp_alloc(type, 0);
- wrapper->obj = (void*)obj;
- wrapper->weakreflist = NULL;
- ret = (PyObject*)wrapper;
- ref = PyWeakref_NewRef(ret, weakref_callback);
- UPB_ASSERT(PyWeakref_GetObject(ref) == ret);
- UPB_ASSERT(ref);
- PyDict_SetItem(obj_cache, kv, ref);
- PyDict_SetItem(reverse_cache, ref, kv);
- }
- UPB_ASSERT(ret);
- Py_DECREF(kv);
- return ret;
-}
-
-
-/* PyUpb_Def ******************************************************************/
-
-static PyTypeObject *PyUpb_TypeForDef(const upb_def *def);
-
-static void PyUpb_Def_dealloc(PyObject *obj) {
- PyUpb_ObjWrapper *wrapper = (void*)obj;
- upb_def_unref((upb_def*)wrapper->obj);
- obj->ob_type->tp_free(obj);
-}
-
-PyObject *PyUpb_Def_GetOrCreate(const upb_def *def) {
- return def ? PyUpb_ObjCacheGet(def, PyUpb_TypeForDef(def)) : Py_None;
-}
-
-// Will need to expand once other kinds of defs are supported.
-#define Check_Def(o, badret) Check_MessageDef(o, badret)
-
-
-/* PyUpb_FieldDef *************************************************************/
-
-static PyTypeObject PyUpb_FieldDefType;
-static int PyUpb_FieldDef_setattro(PyObject *o, PyObject *key, PyObject *val);
-
-#define Check_FieldDef(o, badret) \
- (void*)(((PyUpb_ObjWrapper*)o)->obj); do { \
- if(!PyObject_TypeCheck(o, &PyUpb_FieldDefType)) { \
- PyErr_SetString(PyExc_TypeError, "must be a upb.FieldDef"); \
- return badret; \
- } \
- } while(0)
-
-static PyObject *PyUpb_FieldDef_GetOrCreate(const upb_fielddef *f) {
- return PyUpb_ObjCacheGet(f, &PyUpb_FieldDefType);
-}
-
-static PyObject *PyUpb_FieldDef_new(PyTypeObject *subtype,
- PyObject *args, PyObject *kwds) {
- return PyUpb_ObjCacheGet(upb_fielddef_new(), subtype);
-}
-
-static int PyUpb_FieldDef_init(PyObject *self, PyObject *args, PyObject *kwds) {
- if (!kwds) return 0;
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(kwds, &pos, &key, &value))
- PyUpb_FieldDef_setattro(self, key, value);
- return 0;
-}
-
-static void PyUpb_FieldDef_dealloc(PyObject *obj) {
- PyUpb_ObjWrapper *wrapper = (void*)obj;
- if (wrapper->weakreflist) PyObject_ClearWeakRefs(obj);
- upb_fielddef_unref((upb_fielddef*)wrapper->obj);
- obj->ob_type->tp_free(obj);
-}
-
-static PyObject *PyUpb_FieldDef_getattro(PyObject *obj, PyObject *attr_name) {
- upb_fielddef *f = Check_FieldDef(obj, NULL);
- if (!upb_fielddef_ismutable(f)) {
- PyErr_SetString(PyExc_TypeError, "fielddef is not mutable.");
- return NULL;
- }
- const char *name = PyString_AsString(attr_name);
- if (streql(name, "name")) {
- const char *name = upb_fielddef_name(f);
- return name == NULL ? Py_None : PyString_FromString(name);
- } else if (streql(name, "number")) {
- uint32_t num = upb_fielddef_number(f);
- return num == 0 ? Py_None : PyInt_FromLong(num);
- } else if (streql(name, "type")) {
- uint8_t type = upb_fielddef_type(f);
- return type == 0 ? Py_None : PyInt_FromLong(type);
- } else if (streql(name, "label")) {
- return PyInt_FromLong(upb_fielddef_label(f));
- } else if (streql(name, "type_name")) {
- const char *name = upb_fielddef_typename(f);
- return name == NULL ? Py_None : PyString_FromString(name);
- } else if (streql(name, "subdef")) {
- // NYI;
- return NULL;
- } else if (streql(name, "msgdef")) {
- // NYI;
- return NULL;
- } else {
- return PyUpb_Error("Invalid fielddef member.");
- }
-}
-
-static int PyUpb_FieldDef_setattro(PyObject *o, PyObject *key, PyObject *val) {
- upb_fielddef *f = Check_FieldDef(o, -1);
- const char *field = PyString_AsString(key);
- if (!upb_fielddef_ismutable(f))
- return PyUpb_ErrorInt("fielddef is not mutable.");
- if (streql(field, "name")) {
- const char *name = PyString_AsString(val);
- if (!name || !upb_fielddef_setname(f, name))
- return PyUpb_ErrorInt("Invalid name");
- } else if (streql(field, "number")) {
- // TODO: should check truncation. Non-security issue.
- // Non-int will return -1, which is already invalid as a field number.
- if (!upb_fielddef_setnumber(f, PyInt_AsLong(val)))
- return PyUpb_ErrorInt("Invalid number");
- } else if (streql(field, "type")) {
- // TODO: should check truncation. Non-security issue.
- if (!upb_fielddef_settype(f, PyInt_AsLong(val)))
- return PyUpb_ErrorInt("Invalid type");
- } else if (streql(field, "label")) {
- // TODO: should check truncation. Non-security issue.
- if (!upb_fielddef_setlabel(f, PyInt_AsLong(val)))
- return PyUpb_ErrorInt("Invalid label");
- } else if (streql(field, "type_name")) {
- const char *name = PyString_AsString(val);
- if (!name || !upb_fielddef_settypename(f, name))
- return PyUpb_ErrorInt("Invalid type_name");
- } else if (streql(field, "default_value")) {
- // NYI
- return -1;
- } else {
- return PyUpb_ErrorInt("Invalid fielddef member.");
- }
- return 0;
-}
-
-static PyTypeObject PyUpb_FieldDefType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "upb.FieldDef", /* tp_name */
- sizeof(PyUpb_ObjWrapper), /* tp_basicsize */
- 0, /* tp_itemsize */
- &PyUpb_FieldDef_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* TODO */ /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- &PyUpb_FieldDef_getattro, /* tp_getattro */
- &PyUpb_FieldDef_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyUpb_ObjWrapper, weakreflist),/* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- &PyUpb_FieldDef_init, /* tp_init */
- 0, /* tp_alloc */
- &PyUpb_FieldDef_new, /* tp_new */
- 0, /* tp_free */
-};
-
-
-/* PyUpb_MessageDef ***********************************************************/
-
-static PyTypeObject PyUpb_MessageDefType;
-static int PyUpb_MessageDef_setattro(PyObject *o, PyObject *key, PyObject *val);
-
-#define Check_MessageDef(o, badret) \
- (void*)(((PyUpb_ObjWrapper*)o)->obj); do { \
- if(!PyObject_TypeCheck(o, &PyUpb_MessageDefType)) { \
- PyErr_SetString(PyExc_TypeError, "must be a upb.MessageDef"); \
- return badret; \
- } \
- } while(0)
-
-static PyObject *PyUpb_MessageDef_new(PyTypeObject *subtype,
- PyObject *args, PyObject *kwds) {
- return PyUpb_ObjCacheGet(upb_msgdef_new(), subtype);
-}
-
-static PyObject *PyUpb_MessageDef_add_fields(PyObject *o, PyObject *args);
-
-static int PyUpb_MessageDef_init(
- PyObject *self, PyObject *args, PyObject *kwds) {
- if (!kwds) return 0;
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(kwds, &pos, &key, &value)) {
- const char *field = PyString_AsString(key);
- if (streql(field, "fields")) {
- PyUpb_MessageDef_add_fields(self, value);
- } else {
- PyUpb_MessageDef_setattro(self, key, value);
- }
- }
- return 0;
-}
-
-static PyObject *PyUpb_MessageDef_getattro(PyObject *obj, PyObject *attr_name) {
- upb_msgdef *m = Check_MessageDef(obj, NULL);
- const char *name = PyString_AsString(attr_name);
- if (streql(name, "fqname")) {
- const char *fqname = upb_def_fqname(UPB_UPCAST(m));
- return fqname == NULL ? Py_None : PyString_FromString(fqname);
- }
- return PyObject_GenericGetAttr(obj, attr_name);
-}
-
-static int PyUpb_MessageDef_setattro(
- PyObject *o, PyObject *key, PyObject *val) {
- upb_msgdef *m = Check_MessageDef(o, -1);
- if (!upb_def_ismutable(UPB_UPCAST(m))) {
- PyErr_SetString(PyExc_TypeError, "MessageDef is not mutable.");
- return -1;
- }
- const char *name = PyString_AsString(key);
- if (streql(name, "fqname")) {
- const char *fqname = PyString_AsString(val);
- if (!fqname || !upb_def_setfqname(UPB_UPCAST(m), fqname))
- return PyUpb_ErrorInt("Invalid fqname");
- } else {
- return PyUpb_ErrorInt("Invalid MessageDef member.");
- }
- return 0;
-}
-
-static PyObject *PyUpb_MessageDef_fields(PyObject *obj, PyObject *args) {
- upb_msgdef *m = Check_MessageDef(obj, NULL);
- PyObject *ret = PyList_New(0);
- upb_msg_field_iter i;
- for(upb_msg_field_begin(&i, m);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&ii)) {
- upb_fielddef *f = upb_msg_iter_field(&i);
- PyList_Append(ret, PyUpb_FieldDef_GetOrCreate(f));
- }
- return ret;
-}
-
-static PyObject *PyUpb_MessageDef_add_fields(PyObject *o, PyObject *fields) {
- upb_msgdef *m = Check_MessageDef(o, NULL);
- if (!PySequence_Check(fields)) return PyUpb_Error("Must be a sequence");
- Py_ssize_t len = PySequence_Length(fields);
- if (len > UPB_MAX_FIELDS) return PyUpb_Error("Too many fields.");
- upb_fielddef *f[len];
- int i;
- for (i = 0; i < len; i++) {
- PyObject *field = PySequence_GetItem(fields, i);
- f[i] = Check_FieldDef(field, NULL);
- }
- upb_msgdef_addfields(m, f, len);
- return Py_None;
-}
-
-static PyObject *PyUpb_MessageDef_add_field(PyObject *o, PyObject *field) {
- upb_msgdef *m = Check_MessageDef(o, NULL);
- upb_fielddef *f = Check_FieldDef(field, NULL);
- upb_msgdef_addfield(m, f);
- return Py_None;
-}
-
-static PyMethodDef PyUpb_MessageDef_methods[] = {
- {"add_field", &PyUpb_MessageDef_add_field, METH_O,
- "Adds a list of fields."},
- {"add_fields", &PyUpb_MessageDef_add_fields, METH_O,
- "Adds a list of fields."},
- {"fields", &PyUpb_MessageDef_fields, METH_NOARGS,
- "Returns list of fields."},
- {NULL, NULL}
-};
-
-static PyTypeObject PyUpb_MessageDefType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "upb.MessageDef", /* tp_name */
- sizeof(PyUpb_ObjWrapper), /* tp_basicsize */
- 0, /* tp_itemsize */
- &PyUpb_Def_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* TODO */ /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- &PyUpb_MessageDef_getattro, /* tp_getattro */
- &PyUpb_MessageDef_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyUpb_ObjWrapper, weakreflist),/* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- PyUpb_MessageDef_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- &PyUpb_MessageDef_init, /* tp_init */
- 0, /* tp_alloc */
- &PyUpb_MessageDef_new, /* tp_new */
- 0, /* tp_free */
-};
-
-
-static PyTypeObject *PyUpb_TypeForDef(const upb_def *def) {
- switch(def->type) {
- case UPB_DEF_MSG: return &PyUpb_MessageDefType;
- default: return NULL;
- }
-}
-
-/* PyUpb_SymbolTable **********************************************************/
-
-static PyTypeObject PyUpb_SymbolTableType;
-
-#define Check_SymbolTable(o, badret) \
- (void*)(((PyUpb_ObjWrapper*)o)->obj); do { \
- if(!PyObject_TypeCheck(o, &PyUpb_SymbolTableType)) { \
- PyErr_SetString(PyExc_TypeError, "must be a upb.MessageDef"); \
- return badret; \
- } \
- } while(0)
-
-static PyObject *PyUpb_SymbolTable_new(PyTypeObject *subtype,
- PyObject *args, PyObject *kwds) {
- return PyUpb_ObjCacheGet(upb_symtab_new(), subtype);
-}
-
-static int PyUpb_SymbolTable_init(
- PyObject *self, PyObject *args, PyObject *kwds) {
- return 0;
-}
-
-static void PyUpb_SymbolTable_dealloc(PyObject *obj) {
- PyUpb_ObjWrapper *wrapper = (void*)obj;
- upb_symtab_unref((upb_symtab*)wrapper->obj);
- obj->ob_type->tp_free(obj);
-}
-
-// narg is a lua table containing a list of defs to add.
-static PyObject *PyUpb_SymbolTable_add_defs(PyObject *o, PyObject *defs) {
- upb_symtab *s = Check_SymbolTable(o, NULL);
- if (!PySequence_Check(defs)) return PyUpb_Error("Must be a sequence");
- Py_ssize_t n = PySequence_Length(defs);
-
- // Prevent stack overflow.
- if (n > 2048) return PyUpb_Error("Too many defs");
- upb_def *cdefs[n];
-
- int i = 0;
- for (i = 0; i < n; i++) {
- PyObject *pydef = PySequence_GetItem(defs, i);
- upb_def *def = Check_MessageDef(pydef, NULL);
- cdefs[i++] = def;
- upb_msgdef *md = upb_dyncast_msgdef(def);
- if (!md) continue;
- upb_msg_field_iter j;
- for(upb_msg_field_begin(&j, md);
- !upb_msg_field_done(&j);
- upb_msg_field_next(&j)) {
- upb_fielddef *f = upb_msg_iter_field(j);
- upb_fielddef_setaccessor(f, PyUpb_AccessorForField(f));
- }
- upb_msgdef_layout(md);
- }
-
- upb_status status = UPB_STATUS_INIT;
- upb_symtab_add(s, cdefs, n, &status);
- PyUpb_CheckStatus(&status);
- return Py_None;
-}
-
-static PyObject *PyUpb_SymbolTable_add_def(PyObject *o, PyObject *def) {
- PyObject *defs = PyList_New(1);
- PyList_SetItem(defs, 0, def);
- return PyUpb_SymbolTable_add_defs(o, defs);
-}
-
-// TODO: update to allow user to choose type of defs.
-static PyObject *PyUpb_SymbolTable_defs(PyObject *o, PyObject *none) {
- upb_symtab *s = Check_SymbolTable(o, NULL);
- int count;
- const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
- PyObject *ret = PyList_New(count);
- int i;
- for(i = 0; i < count; i++)
- PyList_SetItem(ret, i, PyUpb_Def_GetOrCreate(defs[i]));
- return ret;
-}
-
-static PyObject *PyUpb_SymbolTable_lookup(PyObject *o, PyObject *arg) {
- upb_symtab *s = Check_SymbolTable(o, NULL);
- const char *name = PyString_AsString(arg);
- const upb_def *def = upb_symtab_lookup(s, name);
- return PyUpb_Def_GetOrCreate(def);
-}
-
-static PyMethodDef PyUpb_SymbolTable_methods[] = {
- {"add_def", &PyUpb_SymbolTable_add_def, METH_O, NULL},
- {"add_defs", &PyUpb_SymbolTable_add_defs, METH_O, NULL},
- {"defs", &PyUpb_SymbolTable_defs, METH_NOARGS, NULL},
- {"lookup", &PyUpb_SymbolTable_lookup, METH_O, NULL},
- {NULL, NULL}
-};
-
-static PyTypeObject PyUpb_SymbolTableType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "upb.SymbolTable", /* tp_name */
- sizeof(PyUpb_ObjWrapper), /* tp_basicsize */
- 0, /* tp_itemsize */
- &PyUpb_SymbolTable_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* TODO */ /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyUpb_ObjWrapper, weakreflist),/* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- PyUpb_SymbolTable_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- &PyUpb_SymbolTable_init, /* tp_init */
- 0, /* tp_alloc */
- &PyUpb_SymbolTable_new, /* tp_new */
- 0, /* tp_free */
-};
-
-
-/* Accessor and PyUpb_Message *************************************************/
-
-typedef struct {
- PyTypeObject type;
- PyTypeObject *alt_type;
-} PyUpb_MessageType;
-
-typedef struct {
- PyObject_HEAD;
- PyObject *msgdef;
- char data[1];
-} PyUpb_Message;
-
-PyObject **PyUpb_Accessor_GetPtr(PyObject *_m, upb_value fval) {
- PyUpb_Message *m = (PyUpb_Message*)_m;
- const upb_fielddef *f = upb_value_getfielddef(fval);
- return (PyObject**)&m->data[f->offset];
-}
-
-static upb_sflow_t PyUpb_Message_StartSequence(void *m, upb_value fval) {
- PyObject **seq = PyUpb_Accessor_GetPtr(m, fval);
- PyTypeObject *type = ((PyUpb_MessageType*)Py_TYPE(m))->alt_type;
- if (!*seq) *seq = type->tp_alloc(type, 0);
- upb_stdmsg_sethas(m, fval);
- return UPB_CONTINUE_WITH(*seq);
-}
-
-static upb_sflow_t PyUpb_Message_StartSubmessage(void *m, upb_value fval) {
- PyObject **submsg = PyUpb_Accessor_GetPtr(m, fval);
- PyTypeObject *type = Py_TYPE(m);
- if (!*submsg) *submsg = type->tp_alloc(type, 0);
- upb_stdmsg_sethas(m, fval);
- return UPB_CONTINUE_WITH(*submsg);
-}
-
-static upb_sflow_t PyUpb_Message_StartRepeatedSubmessage(
- void *a, upb_value fval) {
- (void)fval;
- PyObject **elem = upb_stdarray_append(a, sizeof(void*));
- PyTypeObject *type = ((PyUpb_MessageType*)Py_TYPE(a))->alt_type;
- if (!*elem) *elem = type->tp_alloc(type, 0);
- return UPB_CONTINUE_WITH(*elem);
-}
-
-static upb_flow_t PyUpb_Message_StringValue(
- void *m, upb_value fval, upb_value val) {
- PyObject **str = PyUpb_Accessor_GetPtr(m, fval);
- if (*str) { Py_DECREF(*str); }
- *str = PyString_FromStringAndSize(NULL, upb_value_getstrref(val)->len);
- upb_strref_read(upb_value_getstrref(val), PyString_AsString(*str));
- upb_stdmsg_sethas(m, fval);
- return UPB_CONTINUE;
-}
-
-static upb_flow_t PyUpb_Message_AppendStringValue(
- void *a, upb_value fval, upb_value val) {
- (void)fval;
- PyObject **elem = upb_stdarray_append(a, sizeof(void*));
- *elem = PyString_FromStringAndSize(NULL, upb_value_getstrref(val)->len);
- upb_strref_read(upb_value_getstrref(val), PyString_AsString(*elem));
- return UPB_CONTINUE;
-}
-
-#define STDMSG(type, size) static upb_accessor_vtbl vtbl = { \
- &PyUpb_Message_StartSubmessage, \
- &upb_stdmsg_set ## type, \
- &PyUpb_Message_StartSequence, \
- &PyUpb_Message_StartRepeatedSubmessage, \
- &upb_stdmsg_set ## type ## _r, \
- &upb_stdmsg_has, \
- &upb_stdmsg_getptr, \
- &upb_stdmsg_get ## type, \
- &upb_stdmsg_seqbegin, \
- &upb_stdmsg_ ## size ## byte_seqnext, \
- &upb_stdmsg_seqget ## type};
-
-#define RETURN_STDMSG(type, size) { STDMSG(type, size); return &vtbl; }
-
-static upb_accessor_vtbl *PyUpb_AccessorForField(upb_fielddef *f) {
- switch (f->type) {
- case UPB_TYPE(DOUBLE): RETURN_STDMSG(double, 8)
- case UPB_TYPE(FLOAT): RETURN_STDMSG(float, 4)
- case UPB_TYPE(UINT64):
- case UPB_TYPE(FIXED64): RETURN_STDMSG(uint64, 8)
- case UPB_TYPE(INT64):
- case UPB_TYPE(SFIXED64):
- case UPB_TYPE(SINT64): RETURN_STDMSG(int64, 8)
- case UPB_TYPE(INT32):
- case UPB_TYPE(SINT32):
- case UPB_TYPE(ENUM):
- case UPB_TYPE(SFIXED32): RETURN_STDMSG(int32, 4)
- case UPB_TYPE(UINT32):
- case UPB_TYPE(FIXED32): RETURN_STDMSG(uint32, 4)
- case UPB_TYPE(BOOL): { STDMSG(bool, 1); return &vtbl; }
- case UPB_TYPE(GROUP):
- case UPB_TYPE(MESSAGE): RETURN_STDMSG(ptr, 8) // TODO: 32-bit
- case UPB_TYPE(STRING):
- case UPB_TYPE(BYTES): {
- STDMSG(ptr, 8);
- vtbl.set = &PyUpb_Message_StringValue;
- vtbl.append = &PyUpb_Message_AppendStringValue;
- return &vtbl;
- }
- }
- return NULL;
-}
-
-
-/* Toplevel *******************************************************************/
-
-static PyMethodDef methods[] = {
- {NULL, NULL}
-};
-
-// PyModule_AddObject steals a ref, but our object is statically allocated
-// and must not be deleted.
-#define PyUpb_AddType(mod, name, type) \
- if (PyType_Ready(type) < 0) return; \
- Py_INCREF(type); \
- PyModule_AddObject(mod, name, (PyObject*)type);
-
-PyMODINIT_FUNC initupb(void) {
- PyObject *mod = Py_InitModule("upb", methods);
-
- PyUpb_AddType(mod, "FieldDef", &PyUpb_FieldDefType);
- PyUpb_AddType(mod, "MessageDef", &PyUpb_MessageDefType);
- PyUpb_AddType(mod, "SymbolTable", &PyUpb_SymbolTableType);
-
- PyModule_AddIntConstant(mod, "LABEL_OPTIONAL", UPB_LABEL(OPTIONAL));
- PyModule_AddIntConstant(mod, "LABEL_REQUIRED", UPB_LABEL(REQUIRED));
- PyModule_AddIntConstant(mod, "LABEL_REPEATED", UPB_LABEL(REPEATED));
-
- PyModule_AddIntConstant(mod, "TYPE_DOUBLE", UPB_TYPE(DOUBLE));
- PyModule_AddIntConstant(mod, "TYPE_FLOAT", UPB_TYPE(FLOAT));
- PyModule_AddIntConstant(mod, "TYPE_INT64", UPB_TYPE(INT64));
- PyModule_AddIntConstant(mod, "TYPE_UINT64", UPB_TYPE(UINT64));
- PyModule_AddIntConstant(mod, "TYPE_INT32", UPB_TYPE(INT32));
- PyModule_AddIntConstant(mod, "TYPE_FIXED64", UPB_TYPE(FIXED64));
- PyModule_AddIntConstant(mod, "TYPE_FIXED32", UPB_TYPE(FIXED32));
- PyModule_AddIntConstant(mod, "TYPE_BOOL", UPB_TYPE(BOOL));
- PyModule_AddIntConstant(mod, "TYPE_STRING", UPB_TYPE(STRING));
- PyModule_AddIntConstant(mod, "TYPE_GROUP", UPB_TYPE(GROUP));
- PyModule_AddIntConstant(mod, "TYPE_MESSAGE", UPB_TYPE(MESSAGE));
- PyModule_AddIntConstant(mod, "TYPE_BYTES", UPB_TYPE(BYTES));
- PyModule_AddIntConstant(mod, "TYPE_UINT32", UPB_TYPE(UINT32));
- PyModule_AddIntConstant(mod, "TYPE_ENUM", UPB_TYPE(ENUM));
- PyModule_AddIntConstant(mod, "TYPE_SFIXED32", UPB_TYPE(SFIXED32));
- PyModule_AddIntConstant(mod, "TYPE_SFIXED64", UPB_TYPE(SFIXED64));
- PyModule_AddIntConstant(mod, "TYPE_SINT32", UPB_TYPE(SINT32));
- PyModule_AddIntConstant(mod, "TYPE_SINT64", UPB_TYPE(SINT64));
-
- obj_cache = PyDict_New();
- reverse_cache = PyDict_New();
- static PyMethodDef method = {
- "WeakRefCallback", &PyUpb_ObjCacheDeleteCallback, METH_O, NULL};
- PyObject *pyname = PyString_FromString(method.ml_name);
- weakref_callback = PyCFunction_NewEx(&method, NULL, pyname);
- Py_DECREF(pyname);
-}
diff --git a/upb/bindings/python/upb/__init__.py b/upb/bindings/python/upb/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/upb/bindings/python/upb/__init__.py
+++ /dev/null
diff --git a/upb/bindings/ruby/README.md b/upb/bindings/ruby/README.md
deleted file mode 100644
index 12a7169..0000000
--- a/upb/bindings/ruby/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# Ruby extension
-
-To build, run (from the top upb directory):
-
- $ make ruby
- $ sudo make install
-
-To test, run:
-
- $ make rubytest
-
-The binding currently supports:
-
- - loading message types from descriptors.
- - constructing message instances
- - reading and writing their members
- - parsing and serializing the messages
- - all data types (including nested and repeated)
-
-The binding does *not* currently support:
-
- - defining message types directly in Ruby code.
- - generating Ruby code for a .proto file.
- - type-checking for setters
- - homogenous / type-checked arrays
- - default values
-
-Because code generation is not currently implemented, the interface to import
-a specific message type is kind of clunky for the moment.
diff --git a/upb/bindings/ruby/extconf.rb b/upb/bindings/ruby/extconf.rb
deleted file mode 100644
index b105948..0000000
--- a/upb/bindings/ruby/extconf.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/ruby
-
-require 'mkmf'
-
-# Extra args are passed on the command-line.
-$CFLAGS += (" " + ARGV[0])
-
-find_header("upb/upb.h", "../../..") or raise "Can't find upb headers"
-find_library("upb_pic", "upb_msgdef_new", "../../../lib") or raise "Can't find upb lib"
-find_library("upb.descriptor_pic", "upb_descreader_init", "../../../lib") or raise "Can't find upb.descriptor lib"
-find_library("upb.pb_pic", "upb_pbdecoder_init", "../../../lib") or raise "Can't find upb.pb lib"
-
-create_makefile("upb")
diff --git a/upb/bindings/ruby/upb.c b/upb/bindings/ruby/upb.c
deleted file mode 100644
index 7598bac..0000000
--- a/upb/bindings/ruby/upb.c
+++ /dev/null
@@ -1,1173 +0,0 @@
-/*
-** upb (prototype) extension for Ruby.
-*/
-
-#include "ruby/ruby.h"
-#include "ruby/vm.h"
-
-#include "upb/def.h"
-#include "upb/handlers.h"
-#include "upb/pb/decoder.h"
-#include "upb/pb/encoder.h"
-#include "upb/pb/glue.h"
-#include "upb/shim/shim.h"
-#include "upb/symtab.h"
-
-// References to global state.
-//
-// Ruby does not have multi-VM support and it is common practice to store
-// references to classes and other per-VM state in global variables.
-static VALUE cSymbolTable;
-static VALUE cMessageDef;
-static VALUE cMessage;
-static VALUE message_map;
-static upb_inttable objcache;
-static bool objcache_initialized = false;
-
-struct rupb_Message;
-struct rupb_MessageDef;
-typedef struct rupb_Message rupb_Message;
-typedef struct rupb_MessageDef rupb_MessageDef;
-
-#define DEREF_RAW(ptr, ofs, type) *(type*)((char*)ptr + ofs)
-#define DEREF(msg, ofs, type) *(type*)(&msg->data[ofs])
-
-void rupb_checkstatus(upb_status *s) {
- if (!upb_ok(s)) {
- rb_raise(rb_eRuntimeError, "%s", upb_status_errmsg(s));
- }
-}
-
-static rupb_MessageDef *msgdef_get(VALUE self);
-static rupb_Message *msg_get(VALUE self);
-static const rupb_MessageDef *get_rbmsgdef(const upb_msgdef *md);
-static const upb_handlers *new_fill_handlers(const rupb_MessageDef *rmd,
- const void *owner);
-static void putmsg(rupb_Message *msg, const rupb_MessageDef *rmd,
- upb_sink *sink);
-static VALUE msgdef_getwrapper(const upb_msgdef *md);
-static VALUE new_message_class(VALUE message_def);
-static VALUE get_message_class(VALUE klass, VALUE message);
-static VALUE msg_new(VALUE msgdef);
-
-/* Ruby VALUE <-> C primitive conversions *************************************/
-
-// Ruby VALUE -> C.
-// TODO(haberman): add type/range/precision checks.
-static float value_to_float(VALUE val) { return NUM2DBL(val); }
-static double value_to_double(VALUE val) { return NUM2DBL(val); }
-static bool value_to_bool(VALUE val) { return RTEST(val); }
-static int32_t value_to_int32(VALUE val) { return NUM2INT(val); }
-static uint32_t value_to_uint32(VALUE val) { return NUM2LONG(val); }
-static int64_t value_to_int64(VALUE val) { return NUM2LONG(val); }
-static uint64_t value_to_uint64(VALUE val) { return NUM2ULL(val); }
-
-// C -> Ruby VALUE
-static VALUE float_to_value(float val) { return rb_float_new(val); }
-static VALUE double_to_value(double val) { return rb_float_new(val); }
-static VALUE bool_to_value(bool val) { return val ? Qtrue : Qfalse; }
-static VALUE int32_to_value(int32_t val) { return INT2NUM(val); }
-static VALUE uint32_to_value(uint32_t val) { return LONG2NUM(val); }
-static VALUE int64_to_value(int64_t val) { return LONG2NUM(val); }
-static VALUE uint64_to_value(uint64_t val) { return ULL2NUM(val); }
-
-
-/* stringsink *****************************************************************/
-
-// This should probably be factored into a common upb component.
-
-typedef struct {
- upb_byteshandler handler;
- upb_bytessink sink;
- char *ptr;
- size_t len, size;
-} stringsink;
-
-static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
- stringsink *sink = _sink;
- sink->len = 0;
- return sink;
-}
-
-static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
- size_t len, const upb_bufhandle *handle) {
- UPB_UNUSED(hd);
- UPB_UNUSED(handle);
-
- stringsink *sink = _sink;
- size_t new_size = sink->size;
-
- while (sink->len + len > new_size) {
- new_size *= 2;
- }
-
- if (new_size != sink->size) {
- sink->ptr = realloc(sink->ptr, new_size);
- sink->size = new_size;
- }
-
- memcpy(sink->ptr + sink->len, ptr, len);
- sink->len += len;
-
- return len;
-}
-
-void stringsink_init(stringsink *sink) {
- upb_byteshandler_init(&sink->handler);
- upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
- upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
-
- upb_bytessink_reset(&sink->sink, &sink->handler, sink);
-
- sink->size = 32;
- sink->ptr = malloc(sink->size);
-}
-
-void stringsink_uninit(stringsink *sink) {
- free(sink->ptr);
-}
-
-
-/* object cache ***************************************************************/
-
-// The object cache is a singleton mapping of void* -> Ruby Object.
-// It caches Ruby objects that wrap C objects.
-//
-// When we are wrapping C objects it is desirable to give them identity
-// semantics. In other words, if you reach the same C object via two different
-// paths, it is desirable (and sometimes even required) that you get the same
-// wrapper object both times. If we instead just created a new wrapper object
-// every time you ask for one, we could end up with unexpected results like:
-//
-// f1 = msgdef.field("request_id")
-// f2 = msgdef.field("request_id")
-//
-// # equal? tests identity equality. Returns false without a cache.
-// f1.equal?(f2)
-//
-// We do not register the cache with Ruby's GC, so being in this map will not
-// keep the object alive. This is the desired behavior, because it lets objects
-// be freed if they have no references from Ruby. We do require, though, that
-// objects remove themselves from the map when they are freed. In this respect
-// the cache operates like a weak map where the values are weak.
-
-typedef VALUE createfunc(const void *obj);
-
-// Call to initialize the cache. Should be done once on process startup.
-static void objcache_init() {
- upb_inttable_init(&objcache, UPB_CTYPE_UINT64);
- objcache_initialized = true;
-}
-
-// Call to uninitialize the cache. Should be done once on process shutdown.
-static void objcache_uninit(ruby_vm_t *vm) {
- UPB_ASSERT(objcache_initialized);
- UPB_ASSERT(upb_inttable_count(&objcache) == 0);
-
- objcache_initialized = false;
- upb_inttable_uninit(&objcache);
-}
-
-// Looks up the given object in the cache. If the corresponding Ruby wrapper
-// object is found, returns it, otherwise creates the wrapper and returns that.
-static VALUE objcache_getorcreate(const void *obj, createfunc *func) {
- UPB_ASSERT(objcache_initialized);
-
- upb_value v;
- if (!upb_inttable_lookupptr(&objcache, obj, &v)) {
- v = upb_value_uint64(func(obj));
- upb_inttable_insertptr(&objcache, obj, v);
- }
- return upb_value_getuint64(v);
-}
-
-// Removes the given object from the cache. Should only be called by the code
-// that is freeing the wrapper object.
-static void objcache_remove(const void *obj) {
- UPB_ASSERT(objcache_initialized);
-
- bool removed = upb_inttable_removeptr(&objcache, obj, NULL);
- UPB_ASSERT(removed);
-}
-
-/* message layout *************************************************************/
-
-// We layout Ruby messages using a raw block of C memory. We assign offsets for
-// each member so that instances are laid out like a C struct instead of as
-// instance variables. This saves both memory and CPU.
-
-typedef struct {
- // The size of the block of memory we should allocate for instances.
- size_t size;
-
- // Prototype to memcpy() onto new message instances. Size is "size" above.
- void *prototype;
-
- // An offset for each member, indexed by upb_fielddef_index(f).
- uint32_t *field_offsets;
-} rb_msglayout;
-
-// Returns true for fields where the field value we store is a Ruby VALUE (ie. a
-// direct pointer to another Ruby object) instead of storing the value directly
-// in the message.
-static bool is_ruby_value(const upb_fielddef *f) {
- if (upb_fielddef_isseq(f)) {
- // Repeated fields are pointers to arrays.
- return true;
- }
-
- if (upb_fielddef_issubmsg(f)) {
- // Submessage fields are pointers to submessages.
- return true;
- }
-
- if (upb_fielddef_isstring(f)) {
- // String fields are pointers to string objects.
- return true;
- }
-
- return false;
-}
-
-// General alignment rules are that each type needs to be stored at an address
-// that is a multiple of its size.
-static size_t align_up(size_t val, size_t align) {
- return val % align == 0 ? val : val + align - (val % align);
-}
-
-// Byte size to store each upb type.
-static size_t rupb_sizeof(const upb_fielddef *f) {
- if (is_ruby_value(f)) {
- return sizeof(VALUE);
- }
-
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_BOOL:
- return 1;
- case UPB_TYPE_INT32:
- case UPB_TYPE_UINT32:
- case UPB_TYPE_ENUM:
- case UPB_TYPE_FLOAT:
- return 4;
- case UPB_TYPE_INT64:
- case UPB_TYPE_UINT64:
- case UPB_TYPE_DOUBLE:
- return 8;
- default:
- break;
- }
- UPB_ASSERT(false);
- return 0;
-}
-
-// Calculates offsets for each field.
-//
-// This lets us pack protos like structs instead of storing them like
-// dictionaries. This speeds up a parsing a lot and also saves memory
-// (unless messages are very sparse).
-static void assign_offsets(rb_msglayout *layout, const upb_msgdef *md) {
- layout->field_offsets = ALLOC_N(uint32_t, upb_msgdef_numfields(md));
- size_t ofs = 0;
- upb_msg_field_iter i;
-
- for (upb_msg_field_begin(&i, md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- const upb_fielddef *f = upb_msg_iter_field(&i);
- size_t field_size = rupb_sizeof(f);
-
- // Align field properly.
- //
- // TODO(haberman): optimize layout? For example we could sort fields
- // big-to-small.
- ofs = align_up(ofs, field_size);
-
- layout->field_offsets[upb_fielddef_index(f)] = ofs;
- ofs += field_size;
- }
-
- layout->size = ofs;
-}
-
-// Creates a prototype; a buffer we can memcpy() onto new instances to
-// initialize them.
-static void make_prototype(rb_msglayout *layout, const upb_msgdef *md) {
- void *prototype = ALLOC_N(char, layout->size);
-
- // Most members default to zero, so we'll start from that and then overwrite
- // more specific initialization.
- memset(prototype, 0, layout->size);
-
- upb_msg_field_iter i;
- for (upb_msg_field_begin(&i, md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- const upb_fielddef *f = upb_msg_iter_field(&i);
- if (is_ruby_value(f)) {
- size_t ofs = layout->field_offsets[upb_fielddef_index(f)];
- // Default all Ruby pointers to nil.
- DEREF_RAW(prototype, ofs, VALUE) = Qnil;
- }
- }
-
- layout->prototype = prototype;
-}
-
-
-static void msglayout_init(rb_msglayout *layout, const upb_msgdef *m) {
- assign_offsets(layout, m);
- make_prototype(layout, m);
-}
-
-static void msglayout_uninit(rb_msglayout *layout) {
- free(layout->field_offsets);
- free(layout->prototype);
-}
-
-
-/* Upb::MessageDef ************************************************************/
-
-// C representation for Upb::MessageDef.
-//
-// Contains a reference to the underlying upb_msgdef, as well as associated data
-// like a reference to the corresponding Ruby class.
-struct rupb_MessageDef {
- // We own refs on all of these.
-
- // The upb_msgdef we are wrapping.
- const upb_msgdef *md;
-
- // A DecoderMethod for parsing a protobuf into this type.
- const upb_pbdecodermethod *fill_method;
-
- // Handlers for serializing into a protobuf of this type.
- const upb_handlers *serialize_handlers;
-
- // The Ruby class for instances of this type.
- VALUE klass;
-
- // Layout for messages of this type.
- rb_msglayout layout;
-};
-
-// Called by the Ruby GC when a Upb::MessageDef is being freed.
-static void msgdef_free(void *_rmd) {
- rupb_MessageDef *rmd = _rmd;
- objcache_remove(rmd->md);
- upb_msgdef_unref(rmd->md, &rmd->md);
- if (rmd->fill_method) {
- upb_pbdecodermethod_unref(rmd->fill_method, &rmd->fill_method);
- }
- if (rmd->serialize_handlers) {
- upb_handlers_unref(rmd->serialize_handlers, &rmd->serialize_handlers);
- }
- msglayout_uninit(&rmd->layout);
- free(rmd);
-}
-
-// Called by the Ruby GC during the "mark" phase to decide what is still alive.
-// We call rb_gc_mark on all Ruby VALUE pointers we reference.
-static void msgdef_mark(void *_rmd) {
- rupb_MessageDef *rmd = _rmd;
- rb_gc_mark(rmd->klass);
-
- // Mark all submessage types.
- upb_msg_field_iter i;
- for (upb_msg_field_begin(&i, rmd->md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- upb_fielddef *f = upb_msg_iter_field(&i);
- if (upb_fielddef_issubmsg(f)) {
- // If we were trying to be more aggressively lazy, the submessage might
- // not be created and we only mark ones that are.
- rb_gc_mark(msgdef_getwrapper(upb_fielddef_msgsubdef(f)));
- }
- }
-}
-
-static const rb_data_type_t msgdef_type = {"Upb::MessageDef",
- {msgdef_mark, msgdef_free, NULL}};
-
-// TODO(haberman): do we need an alloc func? We want to prohibit dup and
-// probably subclassing too.
-
-static rupb_MessageDef *msgdef_get(VALUE self) {
- rupb_MessageDef *msgdef;
- TypedData_Get_Struct(self, rupb_MessageDef, &msgdef_type, msgdef);
- return msgdef;
-}
-
-// Constructs the upb decoder method for parsing messages of this type.
-const upb_pbdecodermethod *new_fillmsg_decodermethod(const rupb_MessageDef *rmd,
- const void *owner) {
- const upb_handlers *fill_handlers = new_fill_handlers(rmd, &fill_handlers);
- upb_pbdecodermethodopts opts;
- upb_pbdecodermethodopts_init(&opts, fill_handlers);
-
- const upb_pbdecodermethod *ret = upb_pbdecodermethod_new(&opts, owner);
- upb_handlers_unref(fill_handlers, &fill_handlers);
- return ret;
-}
-
-// Constructs a new Ruby wrapper object around the given msgdef.
-static VALUE make_msgdef(const void *_md) {
- const upb_msgdef *md = _md;
- rupb_MessageDef *rmd;
- VALUE ret =
- TypedData_Make_Struct(cMessageDef, rupb_MessageDef, &msgdef_type, rmd);
-
- upb_msgdef_ref(md, &rmd->md);
-
- rmd->md = md;
- rmd->fill_method = NULL;
-
- // OPT: most of these things could be built lazily, when they are first
- // needed.
- msglayout_init(&rmd->layout, md);
-
- rmd->fill_method = NULL;
- rmd->klass = new_message_class(ret);
- rmd->serialize_handlers =
- upb_pb_encoder_newhandlers(md, &rmd->serialize_handlers);
-
- return ret;
-}
-
-// Accessor to get a decoder method for this message type.
-// Constructs the decoder method lazily.
-static const upb_pbdecodermethod *msgdef_decodermethod(rupb_MessageDef *rmd) {
- if (!rmd->fill_method) {
- rmd->fill_method = new_fillmsg_decodermethod(rmd, &rmd->fill_method);
- }
-
- return rmd->fill_method;
-}
-
-static VALUE msgdef_getwrapper(const upb_msgdef *md) {
- return objcache_getorcreate(md, make_msgdef);
-}
-
-static const rupb_MessageDef *get_rbmsgdef(const upb_msgdef *md) {
- return msgdef_get(msgdef_getwrapper(md));
-}
-
-
-/* Upb::Message ***************************************************************/
-
-// Code to implement the Upb::Message object.
-//
-// A unique Ruby class is generated for each message type, but all message types
-// share Upb::Message as their base class. Upb::Message contains all of the
-// actual functionality; the only reason the derived class exists at all is
-// for convenience. It lets Ruby users do things like:
-//
-// message = MyMessage.new
-// if message.kind_of?(MyMessage)
-//
-// ... and other similar things that Ruby users expect they can do.
-
-// C representation of Upb::Message.
-//
-// Represents a message instance, laid out like a C struct in a type-specific
-// layout.
-//
-// This will be sized according to what fields are actually present.
-struct rupb_Message {
- VALUE rbmsgdef;
- char data[];
-};
-
-// Returns the size of a message instance.
-size_t msg_size(const rupb_MessageDef *rmd) {
- return sizeof(rupb_Message) + rmd->layout.size;
-}
-
-static void msg_free(void *msg) {
- free(msg);
-}
-
-// Invoked by the Ruby GC whenever it is doing a mark-and-sweep.
-static void msg_mark(void *p) {
- rupb_Message *msg = p;
- rupb_MessageDef *rmd = msgdef_get(msg->rbmsgdef);
-
- // Mark the msgdef to keep it alive.
- rb_gc_mark(msg->rbmsgdef);
-
- // We need to mark all references to other Ruby values: strings, arrays, and
- // submessages that we point to.
- upb_msg_field_iter i;
- for (upb_msg_field_begin(&i, rmd->md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- upb_fielddef *f = upb_msg_iter_field(&i);
- if (is_ruby_value(f)) {
- size_t ofs = rmd->layout.field_offsets[upb_fielddef_index(f)];
- rb_gc_mark(DEREF(msg, ofs, VALUE));
- }
- }
-}
-
-static const rb_data_type_t msg_type = {"Upb::Message",
- {msg_mark, msg_free, NULL}};
-
-static rupb_Message *msg_get(VALUE self) {
- rupb_Message *msg;
- TypedData_Get_Struct(self, rupb_Message, &msg_type, msg);
- return msg;
-}
-
-// Instance variable name that we use to store a reference from the Ruby class
-// for a message and its Upb::MessageDef.
-//
-// We avoid prefixing this by "@" to make it inaccessible by Ruby.
-static const char *kMessageDefMemberName = "msgdef";
-
-static VALUE msg_getmsgdef(VALUE klass) {
- VALUE msgdef = rb_iv_get(klass, kMessageDefMemberName);
-
- if (msgdef == Qnil) {
- // TODO(haberman): If we want to allow subclassing, we might want to walk up
- // the hierarchy looking for this member.
- rb_raise(rb_eRuntimeError,
- "Can't call on Upb::Message directly, only subclasses");
- }
-
- return msgdef;
-}
-
-// Called by the Ruby VM when it wants to create a new message instance.
-static VALUE msg_alloc(VALUE klass) {
- VALUE msgdef = msg_getmsgdef(klass);
- const rupb_MessageDef *rmd = msgdef_get(msgdef);
-
- rupb_Message *msg = (rupb_Message*)ALLOC_N(char, msg_size(rmd));
- msg->rbmsgdef = msgdef;
- memcpy(&msg->data, rmd->layout.prototype, rmd->layout.size);
-
- VALUE ret = TypedData_Wrap_Struct(klass, &msg_type, msg);
- return ret;
-}
-
-// Creates a new Ruby class for the given Upb::MessageDef. The new class
-// derives from Upb::Message but also stores a reference to the Upb::MessageDef.
-static VALUE new_message_class(VALUE message_def) {
- msgdef_get(message_def); // Check type.
- VALUE klass = rb_class_new(cMessage);
- rb_iv_set(klass, kMessageDefMemberName, message_def);
-
- // This shouldn't be necessary because we should inherit the alloc func from
- // the base class of Message. For some reason this is not working properly
- // and we are having to define it manually.
- rb_define_alloc_func(klass, msg_alloc);
-
- return klass;
-}
-
-// Call to create a new Message instance.
-static VALUE msg_new(VALUE msgdef) {
- return rb_class_new_instance(0, NULL, get_message_class(Qnil, msgdef));
-}
-
-// Looks up the given field. On success returns the upb_fielddef and stores the
-// offset in *ofs. Otherwise raises a Ruby exception.
-static const upb_fielddef *lookup_field(rupb_Message *msg, const char *field,
- size_t len, size_t *ofs) {
- const rupb_MessageDef *rmd = msgdef_get(msg->rbmsgdef);
- const upb_fielddef *f = upb_msgdef_ntof(rmd->md, field, len);
-
- if (!f) {
- rb_raise(rb_eArgError, "Message %s does not contain field %s",
- upb_msgdef_fullname(rmd->md), field);
- }
-
- *ofs = rmd->layout.field_offsets[upb_fielddef_index(f)];
- return f;
-}
-
-// Sets the given field to the given value.
-static void setprimitive(rupb_Message *m, size_t ofs, const upb_fielddef *f,
- VALUE val) {
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_FLOAT: DEREF(m, ofs, float) = value_to_float(val); break;
- case UPB_TYPE_DOUBLE: DEREF(m, ofs, double) = value_to_double(val); break;
- case UPB_TYPE_BOOL: DEREF(m, ofs, bool) = value_to_bool(val); break;
- case UPB_TYPE_ENUM:
- case UPB_TYPE_INT32: DEREF(m, ofs, int32_t) = value_to_int32(val); break;
- case UPB_TYPE_UINT32: DEREF(m, ofs, uint32_t) = value_to_uint32(val); break;
- case UPB_TYPE_INT64: DEREF(m, ofs, int64_t) = value_to_int64(val); break;
- case UPB_TYPE_UINT64: DEREF(m, ofs, uint64_t) = value_to_uint64(val); break;
- default: rb_bug("Unexpected type");
- }
-}
-
-// Returns the Ruby VALUE for the given field.
-static VALUE getprimitive(rupb_Message *m, size_t ofs, const upb_fielddef *f) {
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_FLOAT: return float_to_value(DEREF(m, ofs, float));
- case UPB_TYPE_DOUBLE: return double_to_value(DEREF(m, ofs, double));
- case UPB_TYPE_BOOL: return bool_to_value(DEREF(m, ofs, bool));
- case UPB_TYPE_ENUM:
- case UPB_TYPE_INT32: return int32_to_value(DEREF(m, ofs, int32_t));
- case UPB_TYPE_UINT32: return uint32_to_value(DEREF(m, ofs, uint32_t));
- case UPB_TYPE_INT64: return int64_to_value(DEREF(m, ofs, int64_t));
- case UPB_TYPE_UINT64: return uint64_to_value(DEREF(m, ofs, uint64_t));
- default: rb_bug("Unexpected type");
- }
-}
-
-static VALUE msg_setter(rupb_Message *msg, VALUE field, VALUE val) {
- size_t ofs;
-
- // fieldp is a string like "id=". But we want to look up "id".
- const upb_fielddef *f =
- lookup_field(msg, RSTRING_PTR(field), RSTRING_LEN(field) - 1, &ofs);
-
- // Possibly introduce stricter type checking.
- if (is_ruby_value(f)) {
- DEREF(msg, ofs, VALUE) = val;
- } else {
- setprimitive(msg, ofs, f, val);
- }
-
- return val;
-}
-
-static VALUE msg_getter(rupb_Message *msg, VALUE field) {
- size_t ofs;
- const upb_fielddef *f =
- lookup_field(msg, RSTRING_PTR(field), RSTRING_LEN(field), &ofs);
-
- if (is_ruby_value(f)) {
- return DEREF(msg, ofs, VALUE);
- } else {
- return getprimitive(msg, ofs, f);
- }
-}
-
-// This is the Message object's "method_missing" method, so it receives calls
-// for any method whose name was not recognized. We use it to implement getters
-// and setters for every field
-//
-// call-seq:
-// message.field -> current value of "field"
-// message.field = new_value
-static VALUE msg_accessor(int argc, VALUE *argv, VALUE obj) {
- rupb_Message *msg = msg_get(obj);
-
- // method_missing protocol: (method [, arg1, arg2, ...])
- UPB_ASSERT(argc >= 1 && SYMBOL_P(argv[0]));
- // OPT(haberman): find a better way to get the method name.
- // This is allocating a new string each time, which should not be necessary.
- VALUE method = rb_id2str(SYM2ID(argv[0]));
- const char *method_str = RSTRING_PTR(method);
- size_t method_len = RSTRING_LEN(method);
-
- if (method_str[method_len - 1] == '=') {
- // Call was:
- // foo.bar = x
- //
- // Ruby should guarantee that we have exactly one more argument (x)
- UPB_ASSERT(argc == 2);
- return msg_setter(msg, method, argv[1]);
- } else {
- // Call was:
- // foo.bar
- //
- // ...but may have had arguments. We want to disallow arguments.
- if (argc > 1) {
- rb_raise(rb_eArgError, "Accessor %s takes no arguments", method_str);
- }
- return msg_getter(msg, method);
- }
-}
-
-// Called when Ruby wants to turn this value into a string.
-// TODO(haberman): implement.
-static VALUE msg_tostring(VALUE self) {
- return rb_str_new2("tostring!");
-}
-
-// call-seq:
-// MessageClass.parse(binary_protobuf) -> message instance
-//
-// Parses a binary protobuf according to this message class and returns a new
-// message instance of this class type.
-static VALUE msg_parse(VALUE klass, VALUE binary_protobuf) {
- Check_Type(binary_protobuf, T_STRING);
- rupb_MessageDef *rmd = msgdef_get(msg_getmsgdef(klass));
-
- VALUE msg = rb_class_new_instance(0, NULL, klass);
- rupb_Message *msgp = msg_get(msg);
-
- const upb_pbdecodermethod *method = msgdef_decodermethod(rmd);
- const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
- upb_pbdecoder decoder;
- upb_sink sink;
- upb_status status = UPB_STATUS_INIT;
-
- upb_pbdecoder_init(&decoder, method, &status);
- upb_sink_reset(&sink, h, msgp);
- upb_pbdecoder_resetoutput(&decoder, &sink);
- upb_bufsrc_putbuf(RSTRING_PTR(binary_protobuf),
- RSTRING_LEN(binary_protobuf),
- upb_pbdecoder_input(&decoder));
-
- // TODO(haberman): make uninit optional if custom allocator for parsing
- // returns GC-rooted memory. That will make decoding longjmp-safe (required
- // if parsing triggers any VM errors like OOM or errors in user handlers).
- upb_pbdecoder_uninit(&decoder);
- rupb_checkstatus(&status);
-
- return msg;
-}
-
-// call-seq:
-// Message.serialize(message instance) -> serialized string
-//
-// Serializes the given message instance to a string.
-static VALUE msg_serialize(VALUE klass, VALUE message) {
- rupb_Message *msg = msg_get(message);
- const rupb_MessageDef *rmd = msgdef_get(msg->rbmsgdef);
-
- stringsink sink;
- stringsink_init(&sink);
-
- upb_pb_encoder encoder;
- upb_pb_encoder_init(&encoder, rmd->serialize_handlers);
- upb_pb_encoder_resetoutput(&encoder, &sink.sink);
-
- putmsg(msg, rmd, upb_pb_encoder_input(&encoder));
-
- VALUE ret = rb_str_new(sink.ptr, sink.len);
-
- upb_pb_encoder_uninit(&encoder);
- stringsink_uninit(&sink);
-
- return ret;
-}
-
-
-/* Upb::SymbolTable ***********************************************************/
-
-// Ruby wrapper around a SymbolTable. Allows loading of descriptors and turning
-// them into MessageDef objects.
-
-void symtab_free(void *s) {
- upb_symtab_unref(s, UPB_UNTRACKED_REF);
-}
-
-static const rb_data_type_t symtab_type = {"Upb::SymbolTable",
- {NULL, symtab_free, NULL}};
-
-// Called by the Ruby VM to allocate a SymbolTable object.
-static VALUE symtab_alloc(VALUE klass) {
- upb_symtab *symtab = upb_symtab_new(UPB_UNTRACKED_REF);
- VALUE ret = TypedData_Wrap_Struct(klass, &symtab_type, symtab);
-
- return ret;
-}
-
-static upb_symtab *symtab_get(VALUE self) {
- upb_symtab *symtab;
- TypedData_Get_Struct(self, upb_symtab, &symtab_type, symtab);
- return symtab;
-}
-
-// call-seq:
-// symtab.load_descriptor(descriptor)
-//
-// Parses a FileDescriptorSet from the given string and adds the defs to the
-// SymbolTable. Raises if there was an error.
-static VALUE symtab_load_descriptor(VALUE self, VALUE descriptor) {
- upb_symtab *symtab = symtab_get(self);
- Check_Type(descriptor, T_STRING);
-
- upb_status status = UPB_STATUS_INIT;
- upb_load_descriptor_into_symtab(
- symtab, RSTRING_PTR(descriptor), RSTRING_LEN(descriptor), &status);
-
- if (!upb_ok(&status)) {
- rb_raise(rb_eRuntimeError,
- "Error loading descriptor: %s", upb_status_errmsg(&status));
- }
-
- return Qnil;
-}
-
-// call-seq:
-// symtab.lookup(name)
-//
-// Returns the def for this name, or nil if none.
-// TODO(haberman): only support messages right now, not enums.
-static VALUE symtab_lookup(VALUE self, VALUE name) {
- upb_symtab *symtab = symtab_get(self);
- Check_Type(name, T_STRING);
-
- const char *cname = RSTRING_PTR(name);
- const upb_msgdef *m = upb_symtab_lookupmsg(symtab, cname);
-
- if (!m) {
- rb_raise(rb_eRuntimeError, "Message name '%s' not found", cname);
- }
-
- return msgdef_getwrapper(m);
-}
-
-
-/* handlers *******************************************************************/
-
-// These are handlers for populating a Ruby protobuf message (rupb_Message) when
-// parsing.
-
-// Creates a handlerdata that simply contains the offset for this field.
-static const void *newhandlerdata(upb_handlers *h, uint32_t ofs) {
- size_t *hd_ofs = ALLOC(size_t);
- *hd_ofs = ofs;
- upb_handlers_addcleanup(h, hd_ofs, free);
- return hd_ofs;
-}
-
-typedef struct {
- size_t ofs;
- const upb_msgdef *md;
-} submsg_handlerdata_t;
-
-// Creates a handlerdata that contains offset and submessage type information.
-static const void *newsubmsghandlerdata(upb_handlers *h, uint32_t ofs,
- const upb_fielddef *f) {
- submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
- hd->ofs = ofs;
- hd->md = upb_fielddef_msgsubdef(f);
- upb_handlers_addcleanup(h, hd, free);
- return hd;
-}
-
-// A handler that starts a repeated field. Gets or creates a Ruby array for the
-// field.
-static void *startseq_handler(void *closure, const void *hd) {
- rupb_Message *msg = closure;
- const size_t *ofs = hd;
-
- if (DEREF(msg, *ofs, VALUE) == Qnil) {
- DEREF(msg, *ofs, VALUE) = rb_ary_new();
- }
-
- return (void*)DEREF(msg, *ofs, VALUE);
-}
-
-// Handlers that append primitive values to a repeated field (a regular Ruby
-// array for now).
-#define DEFINE_APPEND_HANDLER(type, ctype) \
- static bool append##type##_handler(void *closure, const void *hd, \
- ctype val) { \
- VALUE ary = (VALUE)closure; \
- rb_ary_push(ary, type##_to_value(val)); \
- return true; \
- }
-
-DEFINE_APPEND_HANDLER(bool, bool)
-DEFINE_APPEND_HANDLER(int32, int32_t)
-DEFINE_APPEND_HANDLER(uint32, uint32_t)
-DEFINE_APPEND_HANDLER(float, float)
-DEFINE_APPEND_HANDLER(int64, int64_t)
-DEFINE_APPEND_HANDLER(uint64, uint64_t)
-DEFINE_APPEND_HANDLER(double, double)
-
-// Appends a string to a repeated field (a regular Ruby array for now).
-static size_t appendstr_handler(void *closure, const void *hd, const char *str,
- size_t len, const upb_bufhandle *handle) {
- VALUE ary = (VALUE)closure;
- rb_ary_push(ary, rb_str_new(str, len));
- return len;
-}
-
-// Sets a non-repeated string field in a message.
-static size_t str_handler(void *closure, const void *hd, const char *str,
- size_t len, const upb_bufhandle *handle) {
- rupb_Message *msg = closure;
- const size_t *ofs = hd;
- DEREF(msg, *ofs, VALUE) = rb_str_new(str, len);
- return len;
-}
-
-// Appends a submessage to a repeated field (a regular Ruby array for now).
-static void *appendsubmsg_handler(void *closure, const void *hd) {
- VALUE ary = (VALUE)closure;
- const submsg_handlerdata_t *submsgdata = hd;
- VALUE submsg = msg_new(msgdef_getwrapper(submsgdata->md));
- rb_ary_push(ary, submsg);
- return msg_get(submsg);
-}
-
-// Sets a non-repeated submessage field in a message.
-static void *submsg_handler(void *closure, const void *hd) {
- rupb_Message *msg = closure;
- const submsg_handlerdata_t *submsgdata = hd;
-
- if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
- DEREF(msg, submsgdata->ofs, VALUE) =
- msg_new(msgdef_getwrapper(submsgdata->md));
- }
-
- VALUE submsg = DEREF(msg, submsgdata->ofs, VALUE);
- return msg_get(submsg);
-}
-
-static void add_handlers_for_message(const void *closure, upb_handlers *h) {
- const rupb_MessageDef *rmd = get_rbmsgdef(upb_handlers_msgdef(h));
- upb_msg_field_iter i;
-
- for (upb_msg_field_begin(&i, rmd->md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- const upb_fielddef *f = upb_msg_iter_field(&i);
- size_t ofs = rmd->layout.field_offsets[upb_fielddef_index(f)];
-
- if (upb_fielddef_isseq(f)) {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, ofs));
- upb_handlers_setstartseq(h, f, startseq_handler, &attr);
- upb_handlerattr_uninit(&attr);
-
- switch (upb_fielddef_type(f)) {
-
-#define SET_HANDLER(utype, ltype) \
- case utype: \
- upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
- break;
-
- SET_HANDLER(UPB_TYPE_BOOL, bool);
- SET_HANDLER(UPB_TYPE_INT32, int32);
- SET_HANDLER(UPB_TYPE_UINT32, uint32);
- SET_HANDLER(UPB_TYPE_ENUM, int32);
- SET_HANDLER(UPB_TYPE_FLOAT, float);
- SET_HANDLER(UPB_TYPE_INT64, int64);
- SET_HANDLER(UPB_TYPE_UINT64, uint64);
- SET_HANDLER(UPB_TYPE_DOUBLE, double);
-
-#undef SET_HANDLER
-
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- // XXX: does't currently handle split buffers.
- upb_handlers_setstring(h, f, appendstr_handler, NULL);
- break;
- case UPB_TYPE_MESSAGE: {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
- upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
- upb_handlerattr_uninit(&attr);
- break;
- }
- }
- }
-
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_BOOL:
- case UPB_TYPE_INT32:
- case UPB_TYPE_UINT32:
- case UPB_TYPE_ENUM:
- case UPB_TYPE_FLOAT:
- case UPB_TYPE_INT64:
- case UPB_TYPE_UINT64:
- case UPB_TYPE_DOUBLE:
- // The shim writes directly at the given offset (instead of using
- // DEREF()) so we need to add the msg overhead.
- upb_shim_set(h, f, ofs + sizeof(rupb_Message), -1);
- break;
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES: {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, ofs));
- // XXX: does't currently handle split buffers.
- upb_handlers_setstring(h, f, str_handler, &attr);
- upb_handlerattr_uninit(&attr);
- break;
- }
- case UPB_TYPE_MESSAGE: {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, ofs, f));
- upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
- upb_handlerattr_uninit(&attr);
- break;
- }
- }
- }
-}
-
-// Creates upb handlers for populating a message.
-static const upb_handlers *new_fill_handlers(const rupb_MessageDef *rmd,
- const void *owner) {
- return upb_handlers_newfrozen(rmd->md, owner, add_handlers_for_message, NULL);
-}
-
-
-/* msgvisitor *****************************************************************/
-
-// This is code to push the contents of a Ruby message (rupb_Message) to a upb
-// sink.
-
-static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
- upb_selector_t ret;
- bool ok = upb_handlers_getselector(f, type, &ret);
- UPB_ASSERT(ok);
- return ret;
-}
-
-static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
- if (str == Qnil) return;
-
- UPB_ASSERT(BUILTIN_TYPE(str) == RUBY_T_STRING);
- upb_sink subsink;
-
- upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
- &subsink);
- upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
- RSTRING_LEN(str), NULL);
- upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
-}
-
-static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink) {
- if (submsg == Qnil) return;
-
- upb_sink subsink;
- const rupb_MessageDef *sub_rmd = get_rbmsgdef(upb_fielddef_msgsubdef(f));
-
- upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
- putmsg(msg_get(submsg), sub_rmd, &subsink);
- upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
-}
-
-static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink) {
- if (ary == Qnil) return;
-
- UPB_ASSERT(BUILTIN_TYPE(ary) == RUBY_T_ARRAY);
- upb_sink subsink;
-
- upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
-
- upb_fieldtype_t type = upb_fielddef_type(f);
- upb_selector_t sel = 0;
- if (upb_fielddef_isprimitive(f)) {
- sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
- }
-
- int i;
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- VALUE val = rb_ary_entry(ary, i);
- switch (type) {
-
-#define T(upbtypeconst, upbtype, ctype) \
- case upbtypeconst: \
- upb_sink_put##upbtype(&subsink, sel, value_to_##upbtype(val)); \
- break;
-
- T(UPB_TYPE_FLOAT, float, float)
- T(UPB_TYPE_DOUBLE, double, double)
- T(UPB_TYPE_BOOL, bool, bool)
- case UPB_TYPE_ENUM:
- T(UPB_TYPE_INT32, int32, int32_t)
- T(UPB_TYPE_UINT32, uint32, uint32_t)
- T(UPB_TYPE_INT64, int64, int64_t)
- T(UPB_TYPE_UINT64, uint64, uint64_t)
-
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- putstr(val, f, &subsink);
- break;
- case UPB_TYPE_MESSAGE:
- putsubmsg(val, f, &subsink);
- break;
-
-#undef T
-
- }
- }
- upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
-}
-
-static void putmsg(rupb_Message *msg, const rupb_MessageDef *rmd,
- upb_sink *sink) {
- upb_sink_startmsg(sink);
-
- upb_msg_field_iter i;
- for (upb_msg_field_begin(&i, rmd->md);
- !upb_msg_field_done(&i);
- upb_msg_field_next(&i)) {
- upb_fielddef *f = upb_msg_iter_field(&i);
- uint32_t ofs = rmd->layout.field_offsets[upb_fielddef_index(f)];
-
- if (upb_fielddef_isseq(f)) {
- VALUE ary = DEREF(msg, ofs, VALUE);
- if (ary != Qnil) {
- putary(ary, f, sink);
- }
- } else if (upb_fielddef_isstring(f)) {
- putstr(DEREF(msg, ofs, VALUE), f, sink);
- } else if (upb_fielddef_issubmsg(f)) {
- putsubmsg(DEREF(msg, ofs, VALUE), f, sink);
- } else {
- upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
-
-#define T(upbtypeconst, upbtype, ctype) \
- case upbtypeconst: \
- upb_sink_put##upbtype(sink, sel, DEREF(msg, ofs, ctype)); \
- break;
-
- switch (upb_fielddef_type(f)) {
- T(UPB_TYPE_FLOAT, float, float)
- T(UPB_TYPE_DOUBLE, double, double)
- T(UPB_TYPE_BOOL, bool, bool)
- case UPB_TYPE_ENUM:
- T(UPB_TYPE_INT32, int32, int32_t)
- T(UPB_TYPE_UINT32, uint32, uint32_t)
- T(UPB_TYPE_INT64, int64, int64_t)
- T(UPB_TYPE_UINT64, uint64, uint64_t)
-
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error.");
- }
-
-#undef T
-
- }
- }
-
- upb_status status;
- upb_sink_endmsg(sink, &status);
-}
-
-
-/* top level ******************************************************************/
-
-static VALUE get_message_class(VALUE klass, VALUE message) {
- rupb_MessageDef *rmd = msgdef_get(message);
- return rmd->klass;
-}
-
-void Init_upb() {
- VALUE upb = rb_define_module("Upb");
- rb_define_singleton_method(upb, "get_message_class", get_message_class, 1);
- rb_gc_register_address(&message_map);
-
- cSymbolTable = rb_define_class_under(upb, "SymbolTable", rb_cObject);
- rb_define_alloc_func(cSymbolTable, symtab_alloc);
- rb_define_method(cSymbolTable, "load_descriptor", symtab_load_descriptor, 1);
- rb_define_method(cSymbolTable, "lookup", symtab_lookup, 1);
-
- cMessageDef = rb_define_class_under(upb, "MessageDef", rb_cObject);
-
- cMessage = rb_define_class_under(upb, "Message", rb_cObject);
- rb_define_alloc_func(cMessage, msg_alloc);
- rb_define_method(cMessage, "method_missing", msg_accessor, -1);
- rb_define_method(cMessage, "to_s", msg_tostring, 0);
- rb_define_singleton_method(cMessage, "parse", msg_parse, 1);
- rb_define_singleton_method(cMessage, "serialize", msg_serialize, 1);
-
- objcache_init();
-
- // This causes atexit crashes for unknown reasons. :(
- // ruby_vm_at_exit(objcache_uninit);
-}
diff --git a/upb/bindings/stdc++/string.h b/upb/bindings/stdc++/string.h
deleted file mode 100644
index 99efd4f..0000000
--- a/upb/bindings/stdc++/string.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#ifndef UPB_STDCPP_H_
-#define UPB_STDCPP_H_
-
-#include "upb/sink.h"
-
-namespace upb {
-
-template <class T>
-class FillStringHandler {
- public:
- static void SetHandler(BytesHandler* handler) {
- upb_byteshandler_setstartstr(handler, &FillStringHandler::StartString,
- NULL);
- upb_byteshandler_setstring(handler, &FillStringHandler::StringBuf, NULL);
- }
-
- private:
- // TODO(haberman): add UpbBind/UpbMakeHandler support to BytesHandler so these
- // can be prettier callbacks.
- static void* StartString(void *c, const void *hd, size_t size) {
- UPB_UNUSED(hd);
- UPB_UNUSED(size);
-
- T* str = static_cast<T*>(c);
- str->clear();
- return c;
- }
-
- static size_t StringBuf(void* c, const void* hd, const char* buf, size_t n,
- const BufferHandle* h) {
- UPB_UNUSED(hd);
- UPB_UNUSED(h);
-
- T* str = static_cast<T*>(c);
- try {
- str->append(buf, n);
- return n;
- } catch (const std::exception&) {
- return 0;
- }
- }
-};
-
-class StringSink {
- public:
- template <class T>
- explicit StringSink(T* target) {
- // TODO(haberman): we need to avoid rebuilding a new handler every time,
- // but with class globals disallowed for google3 C++ this is tricky.
- FillStringHandler<T>::SetHandler(&handler_);
- input_.Reset(&handler_, target);
- }
-
- BytesSink* input() { return &input_; }
-
- private:
- BytesHandler handler_;
- BytesSink input_;
-};
-
-} // namespace upb
-
-#endif // UPB_STDCPP_H_
diff --git a/upb/bindings/stdc/error.c b/upb/bindings/stdc/error.c
deleted file mode 100644
index 521c1e4..0000000
--- a/upb/bindings/stdc/error.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-** Handling of errno.
-*/
-
-#include "upb/stdc/error.h"
-
-#include <string.h>
-
-void upb_status_fromerrno(upb_status *status, int code) {
- if (code != 0 && !upb_errno_is_wouldblock(code)) {
- status->error = true;
- upb_status_setcode(status, &upb_stdc_errorspace, code);
- }
-}
-
-bool upb_errno_is_wouldblock(int code) {
- return
-#ifdef EAGAIN
- code == EAGAIN ||
-#endif
-#ifdef EWOULDBLOCK
- code == EWOULDBLOCK ||
-#endif
- false;
-}
-
-bool upb_stdc_codetostr(int code, char *buf, size_t len) {
- // strerror() may use static buffers and is not guaranteed to be thread-safe,
- // but it appears that it is not subject to buffer overflows in practice, and
- // it used by other portable and high-quality software like Lua. For more
- // discussion see: http://thread.gmane.org/gmane.comp.lang.lua.general/89506
- char *err = strerror(code);
- if (strlen(err) >= len) return false;
- strcpy(buf, err);
- return true;
-}
-
-upb_errorspace upb_stdc_errorspace = {"stdc", &upb_stdc_codetostr};
diff --git a/upb/bindings/stdc/error.h b/upb/bindings/stdc/error.h
deleted file mode 100644
index 69a2e2b..0000000
--- a/upb/bindings/stdc/error.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-** Handling of errno.
-*/
-
-#include "upb/upb.h"
-
-#ifndef UPB_STDC_ERROR_H_
-#define UPB_STDC_ERROR_H_
-
-UPB_BEGIN_EXTERN_C
-
-extern upb_errorspace upb_stdc_errorspace;
-void upb_status_fromerrno(upb_status *status, int code);
-bool upb_errno_is_wouldblock(int code);
-
-UPB_END_EXTERN_C
-
-#endif /* UPB_STDC_ERROR_H_ */
diff --git a/upb/bindings/stdc/io.c b/upb/bindings/stdc/io.c
deleted file mode 100644
index fe82014..0000000
--- a/upb/bindings/stdc/io.c
+++ /dev/null
@@ -1,172 +0,0 @@
-
-#include "upb/stdc/io.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include "upb/stdc/error.h"
-
-// We can make this configurable if necessary.
-#define BUF_SIZE 32768
-
-/* upb_stdio ******************************************************************/
-
-int upb_stdio_cmpbuf(const void *_key, const void *_elem) {
- const uint64_t *ofs = _key;
- const upb_stdio_buf *buf = _elem;
- return (*ofs / BUF_SIZE) - (buf->ofs / BUF_SIZE);
-}
-
-static upb_stdio_buf *upb_stdio_findbuf(const upb_stdio *s, uint64_t ofs) {
- // TODO: it is probably faster to linear search short lists, and to
- // special-case the last one or two bufs.
- return bsearch(&ofs, s->bufs, s->nbuf, sizeof(*s->bufs), &upb_stdio_cmpbuf);
-}
-
-static upb_stdio_buf *upb_stdio_rotatebufs(upb_stdio *s) {
- upb_stdio_buf **reuse = NULL; // XXX
- int num_reused = 0, num_inuse = 0;
-
- // Could sweep only a subset of bufs if this was a hotspot.
- for (int i = 0; i < s->nbuf; i++) {
- upb_stdio_buf *buf = s->bufs[i];
- if (buf->refcount > 0) {
- s->bufs[num_inuse++] = buf;
- } else {
- reuse[num_reused++] = buf;
- }
- }
- UPB_ASSERT(num_reused + num_inuse == s->nbuf);
- memcpy(s->bufs + num_inuse, reuse, num_reused * sizeof(upb_stdio_buf*));
- if (num_reused == 0) {
- ++s->nbuf;
- s->bufs = realloc(s->bufs, s->nbuf * sizeof(*s->bufs));
- s->bufs[s->nbuf-1] = malloc(sizeof(upb_stdio_buf) + BUF_SIZE);
- return s->bufs[s->nbuf-1];
- }
- return s->bufs[s->nbuf-num_reused];
-}
-
-void upb_stdio_discard(void *src, uint64_t ofs) {
- (void)src;
- (void)ofs;
-}
-
-upb_bytesuccess_t upb_stdio_fetch(void *src, uint64_t ofs, size_t *bytes_read) {
- (void)ofs;
- upb_stdio *stdio = (upb_stdio*)src;
- upb_stdio_buf *buf = upb_stdio_rotatebufs(stdio);
-retry:
- *bytes_read = fread(&buf->data, 1, BUF_SIZE, stdio->file);
- buf->len = *bytes_read;
- if (*bytes_read < (size_t)BUF_SIZE) {
- // Error or EOF.
- if (feof(stdio->file)) {
- upb_status_seteof(&stdio->src.status);
- return UPB_BYTE_EOF;
- }
- if (ferror(stdio->file)) {
-#ifdef EINTR
- // If we encounter a client who doesn't want to retry EINTR, we can easily
- // add a boolean property of the stdio that controls this behavior.
- if (errno == EINTR) {
- clearerr(stdio->file);
- goto retry;
- }
-#endif
- upb_status_fromerrno(&stdio->src.status, errno);
- return upb_errno_is_wouldblock(errno) ?
- UPB_BYTE_WOULDBLOCK : UPB_BYTE_ERROR;
- }
- UPB_ASSERT(false);
- }
- return UPB_BYTE_OK;
-}
-
-void upb_stdio_copy(const void *src, uint64_t ofs, size_t len, char *dst) {
- upb_stdio_buf *buf = upb_stdio_findbuf(src, ofs);
- ofs -= buf->ofs;
- memcpy(dst, buf->data + ofs, BUF_SIZE - ofs);
- len -= (BUF_SIZE - ofs);
- dst += (BUF_SIZE - ofs);
- while (len > 0) {
- ++buf;
- size_t bytes = UPB_MIN(len, BUF_SIZE);
- memcpy(dst, buf->data, bytes);
- len -= bytes;
- dst += bytes;
- }
-}
-
-const char *upb_stdio_getptr(const void *src, uint64_t ofs, size_t *len) {
- upb_stdio_buf *buf = upb_stdio_findbuf(src, ofs);
- ofs -= buf->ofs;
- *len = BUF_SIZE - ofs;
- return &buf->data[ofs];
-}
-
-#if 0
-upb_strlen_t upb_stdio_putstr(upb_bytesink *sink, upb_string *str, upb_status *status) {
- upb_stdio *stdio = (upb_stdio*)((char*)sink - offsetof(upb_stdio, sink));
- upb_strlen_t len = upb_string_len(str);
- upb_strlen_t written = fwrite(upb_string_getrobuf(str), 1, len, stdio->file);
- if (written < len) {
- upb_status_setf(status, UPB_ERROR, "Error writing to stdio stream.");
- return -1;
- }
- return written;
-}
-
-uint32_t upb_stdio_vprintf(upb_bytesink *sink, upb_status *status,
- const char *fmt, va_list args) {
- upb_stdio *stdio = (upb_stdio*)((char*)sink - offsetof(upb_stdio, sink));
- int written = vfprintf(stdio->file, fmt, args);
- if (written < 0) {
- upb_status_seterrf(status, "Error writing to stdio stream.");
- return -1;
- }
- return written;
-}
-#endif
-
-void upb_stdio_init(upb_stdio *stdio) {
- static upb_bytesrc_vtbl bytesrc_vtbl = {
- &upb_stdio_fetch,
- &upb_stdio_discard,
- &upb_stdio_copy,
- &upb_stdio_getptr,
- };
- upb_bytesrc_init(&stdio->src, &bytesrc_vtbl);
-
- //static upb_bytesink_vtbl bytesink_vtbl = {
- // upb_stdio_putstr,
- // upb_stdio_vprintf
- //};
- //upb_bytesink_init(&stdio->bytesink, &bytesink_vtbl);
-}
-
-void upb_stdio_reset(upb_stdio* stdio, FILE *file) {
- stdio->file = file;
- stdio->should_close = false;
-}
-
-void upb_stdio_open(upb_stdio *stdio, const char *filename, const char *mode,
- upb_status *s) {
- FILE *f = fopen(filename, mode);
- if (!f) {
- upb_status_fromerrno(s, errno);
- return;
- }
- setvbuf(stdio->file, NULL, _IONBF, 0); // Disable buffering; we do our own.
- upb_stdio_reset(stdio, f);
- stdio->should_close = true;
-}
-
-void upb_stdio_uninit(upb_stdio *stdio) {
- // Can't report status; caller should flush() to ensure data is written.
- if (stdio->should_close) fclose(stdio->file);
- stdio->file = NULL;
-}
-
-upb_bytesrc* upb_stdio_bytesrc(upb_stdio *stdio) { return &stdio->src; }
-upb_bytesink* upb_stdio_bytesink(upb_stdio *stdio) { return &stdio->sink; }
diff --git a/upb/bindings/stdc/io.h b/upb/bindings/stdc/io.h
deleted file mode 100644
index b131500..0000000
--- a/upb/bindings/stdc/io.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-** ANSI C file I/O.
-*/
-
-#ifndef UPB_STDC_IO_H_
-#define UPB_STDC_IO_H_
-
-#include <stdio.h>
-#include "upb/bytestream.h"
-
-UPB_BEGIN_EXTERN_C
-
-/* upb_stdio ******************************************************************/
-
-// bytesrc/bytesink for ANSI C stdio, which is less efficient than posixfd, but
-// more portable.
-//
-// Specifically, stdio functions acquire locks on every operation (unless you
-// use the f{read,write,...}_unlocked variants, which are not standard) and
-// performs redundant buffering (unless you disable it with setvbuf(), but we
-// can only do this on newly-opened filehandles).
-
-typedef struct {
- uint64_t ofs;
- size_t len;
- uint32_t refcount;
- char data[];
-} upb_stdio_buf;
-
-// We use a single object for both bytesrc and bytesink for simplicity.
-// The object is still not thread-safe, and may only be used by one reader
-// and one writer at a time.
-typedef struct {
- upb_bytesrc src;
- upb_bytesink sink;
- FILE *file;
- bool should_close;
- upb_stdio_buf **bufs;
- int nbuf;
- uint32_t szbuf;
-} upb_stdio;
-
-void upb_stdio_init(upb_stdio *stdio);
-// Caller should call upb_stdio_flush prior to calling this to ensure that
-// all data is flushed, otherwise data can be silently dropped if an error
-// occurs flushing the remaining buffers.
-void upb_stdio_uninit(upb_stdio *stdio);
-
-// Resets the object to read/write to the given "file." The caller is
-// responsible for closing the file, which must outlive this object.
-void upb_stdio_reset(upb_stdio *stdio, FILE *file);
-
-// As an alternative to upb_stdio_reset(), initializes the object by opening a
-// file, and will handle closing it. This may result in more efficient I/O
-// than the previous since we can call setvbuf() to disable buffering.
-void upb_stdio_open(upb_stdio *stdio, const char *filename, const char *mode,
- upb_status *s);
-
-upb_bytesrc *upb_stdio_bytesrc(upb_stdio *stdio);
-upb_bytesink *upb_stdio_bytesink(upb_stdio *stdio);
-
-UPB_END_EXTERN_C
-
-#endif /* UPB_STDC_IO_H_ */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback