summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
Diffstat (limited to 'upb')
-rw-r--r--upb/bindings/googlepb/bridge.cc114
-rw-r--r--upb/bindings/googlepb/bridge.h65
-rw-r--r--upb/bindings/googlepb/proto1.cc27
-rw-r--r--upb/bindings/googlepb/proto1.int.h (renamed from upb/bindings/googlepb/proto1.h)16
-rw-r--r--upb/bindings/googlepb/proto2.cc271
-rw-r--r--upb/bindings/googlepb/proto2.int.h (renamed from upb/bindings/googlepb/proto2.h)18
-rw-r--r--upb/bindings/lua/table.c13
-rw-r--r--upb/bindings/lua/upb.c1736
-rw-r--r--upb/bindings/lua/upb.h106
-rw-r--r--upb/bindings/lua/upb.lua146
-rw-r--r--upb/bindings/lua/upb.pb.c106
-rw-r--r--upb/bindings/lua/upb/descriptor.c20
-rw-r--r--upb/bindings/stdc++/string.h2
-rw-r--r--upb/def.c302
-rw-r--r--upb/def.h214
-rwxr-xr-xupb/descriptor/descriptor.upb.c618
-rwxr-xr-xupb/descriptor/descriptor.upb.h825
-rw-r--r--upb/descriptor/reader.c80
-rw-r--r--upb/handlers-inl.h28
-rw-r--r--upb/handlers.c33
-rw-r--r--upb/handlers.h42
-rw-r--r--upb/json/typed_printer.c322
-rw-r--r--upb/json/typed_printer.h116
-rw-r--r--upb/pb/compile_decoder.c9
-rw-r--r--upb/pb/compile_decoder_x64.dasc3
-rw-r--r--upb/pb/decoder.c146
-rw-r--r--upb/pb/decoder.h22
-rw-r--r--upb/pb/decoder.int.h8
-rw-r--r--upb/pb/textprinter.c18
-rw-r--r--upb/refcounted.c44
-rw-r--r--upb/shim/shim.c3
-rw-r--r--upb/sink.h5
-rw-r--r--upb/symtab.c93
-rw-r--r--upb/symtab.h91
-rw-r--r--upb/table.c144
-rw-r--r--upb/table.int.h94
-rw-r--r--upb/upb.h2
37 files changed, 4135 insertions, 1767 deletions
diff --git a/upb/bindings/googlepb/bridge.cc b/upb/bindings/googlepb/bridge.cc
index c8e3474..a666ff6 100644
--- a/upb/bindings/googlepb/bridge.cc
+++ b/upb/bindings/googlepb/bridge.cc
@@ -16,8 +16,8 @@
#include <map>
#include <string>
#include "upb/def.h"
-#include "upb/bindings/googlepb/proto1.h"
-#include "upb/bindings/googlepb/proto2.h"
+#include "upb/bindings/googlepb/proto1.int.h"
+#include "upb/bindings/googlepb/proto2.int.h"
#include "upb/handlers.h"
#define ASSERT_STATUS(status) do { \
@@ -39,31 +39,24 @@ namespace goog = ::proto2;
namespace goog = ::google::protobuf;
#endif
-namespace {
-
-const goog::Message* GetPrototype(const goog::Message& m,
- const goog::FieldDescriptor* f) {
- const goog::Message* ret = NULL;
-#ifdef UPB_GOOGLE3
- ret = upb::google::GetProto1WeakPrototype(m, f);
- if (ret) return ret;
-#endif
+namespace upb {
+namespace googlepb {
- if (f->cpp_type() == goog::FieldDescriptor::CPPTYPE_MESSAGE) {
- ret = upb::google::GetFieldPrototype(m, f);
+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::google::GetProto1FieldPrototype(m, f);
+ if (!ret) ret = upb::googlepb::GetProto1FieldPrototype(m, f);
#endif
- assert(ret);
- }
return ret;
}
-} // namespace
-
-namespace upb {
-namespace googlepb {
-
+const goog::Message* GetFieldPrototype(const goog::Message& m,
+ const goog::FieldDescriptor* f) {
+ const goog::Message* ret = TryGetFieldPrototype(m, f);
+ assert(ret);
+ return ret;
+}
/* DefBuilder ****************************************************************/
@@ -117,20 +110,11 @@ const MessageDef* DefBuilder::GetMaybeUnfrozenMessageDef(
reffed_ptr<FieldDef> DefBuilder::NewFieldDef(const goog::FieldDescriptor* f,
const goog::Message* m) {
- const goog::Message* subm = NULL;
- const goog::Message* weak_prototype = NULL;
-
- if (m) {
-#ifdef UPB_GOOGLE3
- weak_prototype = upb::google::GetProto1WeakPrototype(*m, f);
-#endif
- subm = GetPrototype(*m, f);
- }
-
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()));
#ifdef UPB_GOOGLE3
upb_f->set_lazy(f->options().lazy());
#endif
@@ -142,11 +126,19 @@ reffed_ptr<FieldDef> DefBuilder::NewFieldDef(const goog::FieldDescriptor* f,
upb_f->set_name(f->name(), &status);
}
- // For weak fields, weak_prototype will be non-NULL even though the proto2
- // descriptor does not indicate a submessage field.
- upb_f->set_descriptor_type(weak_prototype
- ? UPB_DESCRIPTOR_TYPE_MESSAGE
- : FieldDef::ConvertDescriptorType(f->type()));
+ const goog::Message* subm = NULL;
+
+ if (m) {
+ subm = TryGetFieldPrototype(*m, f);
+
+ if (upb_f->type() == UPB_TYPE_MESSAGE) {
+ 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:
@@ -213,6 +205,35 @@ const MessageDef* DefBuilder::GetMessageDefExpandWeak(
}
+/* 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(
@@ -234,21 +255,11 @@ const Handlers* CodeCache::GetMaybeUnfrozenWriteHandlers(
}
assert(proto2_f);
- if (!upb::google::TrySetWriteHandlers(proto2_f, m, upb_f, h)
-#ifdef UPB_GOOGLE3
- && !upb::google::TrySetProto1WriteHandlers(proto2_f, m, upb_f, h)
-#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.
- assert(false);
- }
+ bool ok = WriteHandlers::AddFieldHandler(m, proto2_f, h);
+ UPB_ASSERT_VAR(ok, ok);
if (upb_f->type() == UPB_TYPE_MESSAGE) {
- const goog::Message* prototype = GetPrototype(m, proto2_f);
+ const goog::Message* prototype = GetFieldPrototype(m, proto2_f);
assert(prototype);
const upb::Handlers* sub_handlers =
GetMaybeUnfrozenWriteHandlers(upb_f->message_subdef(), *prototype);
@@ -269,10 +280,5 @@ const Handlers* CodeCache::GetWriteHandlers(const goog::Message& m) {
return ret;
}
-upb::reffed_ptr<const upb::Handlers> NewWriteHandlers(const goog::Message& m) {
- CodeCache cache;
- return upb::reffed_ptr<const upb::Handlers>(cache.GetWriteHandlers(m));
-}
-
} // namespace googlepb
} // namespace upb
diff --git a/upb/bindings/googlepb/bridge.h b/upb/bindings/googlepb/bridge.h
index 9eed51b..9878247 100644
--- a/upb/bindings/googlepb/bridge.h
+++ b/upb/bindings/googlepb/bridge.h
@@ -63,13 +63,6 @@ namespace upb {
namespace googlepb {
-// 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.
-upb::reffed_ptr<const upb::Handlers> NewWriteHandlers(const proto2::Message& m);
-upb::reffed_ptr<const upb::Handlers> NewWriteHandlers(
- const ::google::protobuf::Message& m);
-
// 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.
@@ -159,6 +152,41 @@ class DefBuilder {
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.
@@ -199,6 +227,29 @@ class CodeCache {
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
diff --git a/upb/bindings/googlepb/proto1.cc b/upb/bindings/googlepb/proto1.cc
index c317cdf..0b46fed 100644
--- a/upb/bindings/googlepb/proto1.cc
+++ b/upb/bindings/googlepb/proto1.cc
@@ -16,13 +16,20 @@
// 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.h"
+#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
+
#include "upb/def.h"
#include "upb/handlers.h"
#include "upb/shim/shim.h"
@@ -36,7 +43,7 @@ template <class T> static T* GetPointer(void* message, size_t offset) {
}
namespace upb {
-namespace google {
+namespace googlepb {
class P2R_Handlers {
public:
@@ -466,18 +473,18 @@ class P2R_Handlers {
bool TrySetProto1WriteHandlers(const proto2::FieldDescriptor* proto2_f,
const proto2::Message& m,
const upb::FieldDef* upb_f, upb::Handlers* h) {
- return P2R_Handlers::TrySet(proto2_f, m, upb_f, h);
-}
-
-const proto2::Message* GetProto1WeakPrototype(
- const proto2::Message& m, const proto2::FieldDescriptor* f) {
- return P2R_Handlers::GetWeakPrototype(m, f);
+ return googlepb::P2R_Handlers::TrySet(proto2_f, m, upb_f, h);
}
const proto2::Message* GetProto1FieldPrototype(
const proto2::Message& m, const proto2::FieldDescriptor* f) {
- return P2R_Handlers::GetFieldPrototype(m, 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 google
+} // namespace googlepb
} // namespace upb
diff --git a/upb/bindings/googlepb/proto1.h b/upb/bindings/googlepb/proto1.int.h
index eb550ac..64ebb2f 100644
--- a/upb/bindings/googlepb/proto1.h
+++ b/upb/bindings/googlepb/proto1.int.h
@@ -7,8 +7,7 @@
// Support for registering field handlers that can write into a legacy proto1
// message. This functionality is only needed inside Google.
//
-// This is a low-level interface; the high-level interface in google.h is
-// more user-friendly.
+// This is an internal-only interface.
#ifndef UPB_GOOGLE_PROTO1_H_
#define UPB_GOOGLE_PROTO1_H_
@@ -24,7 +23,7 @@ class Handlers;
}
namespace upb {
-namespace google {
+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
@@ -35,17 +34,12 @@ 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 field in "m", if it is weak. The returned
-// message could be the linked-in message type or OpaqueMessage, if the weak
-// message is *not* linked in. Otherwise returns NULL.
-const proto2::Message* GetProto1WeakPrototype(const proto2::Message& m,
- const proto2::FieldDescriptor* f);
-
-// Returns a prototype for the given non-weak field in "m".
+// 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 google
+} // namespace googlepb
} // namespace upb
#endif // UPB_GOOGLE_PROTO1_H_
diff --git a/upb/bindings/googlepb/proto2.cc b/upb/bindings/googlepb/proto2.cc
index 04e504b..224e2b9 100644
--- a/upb/bindings/googlepb/proto2.cc
+++ b/upb/bindings/googlepb/proto2.cc
@@ -13,10 +13,12 @@
// 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.h"
+#include "upb/bindings/googlepb/proto2.int.h"
+
+#include <map>
#include "upb/def.h"
-#include "upb/bindings/googlepb/proto1.h"
+#include "upb/bindings/googlepb/proto1.int.h"
#include "upb/handlers.h"
#include "upb/shim/shim.h"
#include "upb/sink.h"
@@ -237,10 +239,26 @@ case goog::FieldDescriptor::cpptype: \
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) {
+ 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) {
- return r->offsets_[f->index()];
+ 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];
}
class FieldOffset {
@@ -274,6 +292,154 @@ case goog::FieldDescriptor::cpptype: \
int8_t mask_;
};
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ class OneofFieldData {
+ public:
+ OneofFieldData(const goog::FieldDescriptor* f,
+ const goog::internal::GeneratedMessageReflection* 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_);
+ }
+
+ // 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 {
+ 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
+ }
+ *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:
+ 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(
@@ -352,7 +518,16 @@ case goog::FieldDescriptor::cpptype: \
CHKRET(h->SetValueHandler<T>(
f, UpbBindT(SetPrimitiveExtension<T>, data.release())));
}
- } else {
+ }
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ else if (proto2_f->containing_oneof()) {
+ 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>)));
@@ -383,6 +558,17 @@ case goog::FieldDescriptor::cpptype: \
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 {
@@ -506,7 +692,15 @@ case goog::FieldDescriptor::cpptype: \
upb::Handlers* h) {
assert(!proto2_f->is_extension());
CHKRET(h->SetStringHandler(f, UpbMakeHandlerT(&OnStringBuf<T>)));
- if (f->IsSequence()) {
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ if (proto2_f->containing_oneof()) {
+ 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>)));
@@ -545,6 +739,22 @@ case goog::FieldDescriptor::cpptype: \
return str;
}
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ template <typename T>
+ static T* StartOneofString(goog::Message* m,
+ const OneofFieldHandlerData* data,
+ size_t size_hint) {
+ const FieldOffset* ofs = data;
+ T** str = ofs->GetFieldPointer<T*>(m);
+ if (data->SetOneofHas(m)) {
+ *str = new T();
+ } else {
+ (*str)->clear();
+ }
+ return *str;
+ }
+#endif
+
// StringExtension ///////////////////////////////////////////////////////////
template <typename T>
@@ -598,6 +808,24 @@ case goog::FieldDescriptor::cpptype: \
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,
@@ -605,7 +833,15 @@ case goog::FieldDescriptor::cpptype: \
const goog::Message* field_prototype = GetFieldPrototype(m, proto2_f);
scoped_ptr<SubMessageHandlerData> data(
new SubMessageHandlerData(proto2_f, r, field_prototype));
- if (f->IsSequence()) {
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ if (proto2_f->containing_oneof()) {
+ 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())));
@@ -649,6 +885,18 @@ case goog::FieldDescriptor::cpptype: \
return submsg;
}
+#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)) {
+ *subm = data->prototype()->New();
+ }
+ return *subm;
+ }
+#endif
+
// SubMessageExtension ///////////////////////////////////////////////////////
class SubMessageExtensionHandlerData : public ExtensionFieldData {
@@ -979,7 +1227,7 @@ case goog::FieldDescriptor::cpptype: \
};
namespace upb {
-namespace google {
+namespace googlepb {
bool TrySetWriteHandlers(const goog::FieldDescriptor* proto2_f,
const goog::Message& prototype,
@@ -987,10 +1235,13 @@ bool TrySetWriteHandlers(const goog::FieldDescriptor* proto2_f,
return me::GMR_Handlers::TrySet(proto2_f, prototype, upb_f, h);
}
-const goog::Message* GetFieldPrototype(const goog::Message& m,
- const goog::FieldDescriptor* f) {
+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 google
+} // namespace googlepb
} // namespace upb
diff --git a/upb/bindings/googlepb/proto2.h b/upb/bindings/googlepb/proto2.int.h
index 516b7fd..5ce44c4 100644
--- a/upb/bindings/googlepb/proto2.h
+++ b/upb/bindings/googlepb/proto2.int.h
@@ -8,8 +8,7 @@
// message that uses GeneratedMessageReflection (which includes all messages
// generated by the proto2 compiler as well as DynamicMessage).
//
-// This is a low-level interface; the high-level interface in google.h is
-// more user-friendly.
+// This is an internal-only interface.
#ifndef UPB_GOOGLE_PROTO2_H_
#define UPB_GOOGLE_PROTO2_H_
@@ -32,7 +31,7 @@ class Handlers;
}
namespace upb {
-namespace google {
+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
@@ -46,16 +45,15 @@ 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 it is weak. The returned
-// message could be the linked-in message type or OpaqueMessage, if the weak
-// message is *not* linked in. Otherwise returns NULL.
-const proto2::Message* GetFieldPrototype(const proto2::Message& m,
- const proto2::FieldDescriptor* f);
-const ::google::protobuf::Message* GetFieldPrototype(
+// 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 google
+} // namespace googlepb
} // namespace upb
#endif // UPB_GOOGLE_PROTO2_H_
diff --git a/upb/bindings/lua/table.c b/upb/bindings/lua/table.c
index 51ba324..febadf0 100644
--- a/upb/bindings/lua/table.c
+++ b/upb/bindings/lua/table.c
@@ -25,6 +25,7 @@
#include "lauxlib.h"
#include "upb/bindings/lua/upb.h"
#include "upb/def.h"
+#include "upb/symtab.h"
static void lupbtable_setnum(lua_State *L, int tab, const char *key,
lua_Number val) {
@@ -141,6 +142,12 @@ static int lupbtable_enumdef_ntoi(lua_State *L) {
return 1;
}
+static int lupbtable_symtab_symtab(lua_State *L) {
+ const upb_symtab *s = lupb_symtab_check(L, 1);
+ lupbtable_pushstrtable(L, &s->symtab);
+ return 1;
+}
+
static void lupbtable_setfieldi(lua_State *L, const char *field, int i) {
lua_pushnumber(L, i);
lua_setfield(L, -2, field);
@@ -151,11 +158,15 @@ static const struct luaL_Reg lupbtable_toplevel_m[] = {
{"msgdef_ntof", lupbtable_msgdef_ntof},
{"enumdef_iton", lupbtable_enumdef_iton},
{"enumdef_ntoi", lupbtable_enumdef_ntoi},
+ {"symtab_symtab", lupbtable_symtab_symtab},
{NULL, NULL}
};
int luaopen_upbtable(lua_State *L) {
- lupb_newlib(L, "upb.table", lupbtable_toplevel_m);
+ static char module_key;
+ if (lupb_openlib(L, &module_key, "upb.table", lupbtable_toplevel_m)) {
+ return 1;
+ }
// We define these here because they are not public.
lupbtable_setfieldi(L, "CTYPE_PTR", UPB_CTYPE_PTR);
diff --git a/upb/bindings/lua/upb.c b/upb/bindings/lua/upb.c
index 022d689..dbeb937 100644
--- a/upb/bindings/lua/upb.c
+++ b/upb/bindings/lua/upb.c
@@ -6,6 +6,21 @@
*
* A Lua extension for upb. Exposes only the core library
* (sub-libraries are exposed in other extensions).
+ *
+ * 64-bit woes: Lua can only represent numbers of type lua_Number (which is
+ * double unless the user specifically overrides this). Doubles can represent
+ * the entire range of 64-bit integers, but lose precision once the integers are
+ * greater than 2^53.
+ *
+ * Lua 5.3 is adding support for integers, which will allow for 64-bit
+ * integers (which can be interpreted as signed or unsigned).
+ *
+ * LuaJIT supports 64-bit signed and unsigned boxed representations
+ * through its "cdata" mechanism, but this is not portable to regular Lua.
+ *
+ * Hopefully Lua 5.3 will come soon enough that we can either use Lua 5.3
+ * integer support or LuaJIT 64-bit cdata for users that need the entire
+ * domain of [u]int64 values.
*/
#include <float.h>
@@ -16,8 +31,15 @@
#include "upb/bindings/lua/upb.h"
#include "upb/handlers.h"
#include "upb/pb/glue.h"
+#include "upb/shim/shim.h"
+
+static const char upb_lua[] = {
+#include "upb/bindings/lua/upb.lua.h"
+};
// Lua metatable types.
+#define LUPB_MSG "lupb.msg"
+#define LUPB_ARRAY "lupb.array"
#define LUPB_MSGDEF "lupb.msgdef"
#define LUPB_ENUMDEF "lupb.enumdef"
#define LUPB_FIELDDEF "lupb.fielddef"
@@ -26,6 +48,15 @@
// Other table constants.
#define LUPB_OBJCACHE "lupb.objcache"
+static void lupb_msgdef_init(lua_State *L);
+static size_t lupb_msgdef_sizeof();
+
+/* Lua compatibility code *****************************************************/
+
+// Lua 5.1 and Lua 5.2 have slightly incompatible APIs. A little bit of
+// compatibility code can help hide the difference. Not too many people still
+// use Lua 5.1 but LuaJIT uses the Lua 5.1 API in some ways.
+
#if LUA_VERSION_NUM == 501
// Taken from Lua 5.2's source.
@@ -43,6 +74,12 @@ void *luaL_testudata(lua_State *L, int ud, const char *tname) {
return NULL; /* value is not a userdata with a metatable */
}
+static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) {
+ luaL_register(L, name, funcs);
+}
+
+#define lupb_setfuncs(L, l) luaL_register(L, NULL, l)
+
#elif LUA_VERSION_NUM == 502
int luaL_typerror(lua_State *L, int narg, const char *tname) {
@@ -51,11 +88,72 @@ int luaL_typerror(lua_State *L, int narg, const char *tname) {
return luaL_argerror(L, narg, msg);
}
+static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) {
+ // Lua 5.2 modules are not expected to set a global variable, so "name" is
+ // unused.
+ UPB_UNUSED(name);
+
+ // Can't use luaL_newlib(), because funcs is not the actual array.
+ // Could (micro-)optimize this a bit to count funcs for initial table size.
+ lua_createtable(L, 0, 8);
+ luaL_setfuncs(L, funcs, 0);
+}
+
+#define lupb_setfuncs(L, l) luaL_setfuncs(L, l, 0)
+
#else
#error Only Lua 5.1 and 5.2 are supported
#endif
-static const char *chkname(lua_State *L, int narg) {
+// Shims for upcoming Lua 5.3 functionality.
+bool lua_isinteger(lua_State *L, int argn) {
+ UPB_UNUSED(L);
+ UPB_UNUSED(argn);
+ return false;
+}
+
+
+/* Utility functions **********************************************************/
+
+// We store our module table in the registry, keyed by ptr.
+// For more info about the motivation/rationale, see this thread:
+// http://thread.gmane.org/gmane.comp.lang.lua.general/110632
+bool lupb_openlib(lua_State *L, void *ptr, const char *name,
+ const luaL_Reg *funcs) {
+ // Lookup cached module table.
+ lua_pushlightuserdata(L, ptr);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (!lua_isnil(L, -1)) {
+ return true;
+ }
+
+ lupb_newlib(L, name, funcs);
+
+ // Save module table in cache.
+ lua_pushlightuserdata(L, ptr);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+
+ return false;
+}
+
+// Pushes a new userdata with the given metatable and ensures that it has a
+// uservalue.
+static void *newudata_with_userval(lua_State *L, size_t size, const char *type) {
+ void *ret = lua_newuserdata(L, size);
+
+ // Set metatable.
+ luaL_getmetatable(L, type);
+ assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb.
+ lua_setmetatable(L, -2);
+
+ lua_newtable(L);
+ lua_setuservalue(L, -2);
+
+ return ret;
+}
+
+const char *lupb_checkname(lua_State *L, int narg) {
size_t len;
const char *name = luaL_checklstring(L, narg, &len);
if (strlen(name) != len)
@@ -63,65 +161,110 @@ static const char *chkname(lua_State *L, int narg) {
return name;
}
-static bool chkbool(lua_State *L, int narg, const char *type) {
+bool lupb_checkbool(lua_State *L, int narg) {
if (!lua_isboolean(L, narg)) {
- luaL_error(L, "%s must be true or false", type);
+ luaL_error(L, "must be true or false");
}
return lua_toboolean(L, narg);
}
-static bool streql(const char *a, const char *b) { return strcmp(a, b) == 0; }
+// Unlike luaL_checkstring(), this does not allow implicit conversion to string.
+void lupb_checkstring(lua_State *L, int narg) {
+ if (lua_type(L, narg) != LUA_TSTRING)
+ luaL_error(L, "Expected string");
+}
+
+// Unlike luaL_checkinteger, these do not implicitly convert from string or
+// round an existing double value. We allow floating-point input, but only if
+// the actual value is integral.
+#define INTCHECK(type, ctype) \
+ ctype lupb_check##type(lua_State *L, int narg) { \
+ if (lua_isinteger(L, narg)) { \
+ return lua_tointeger(L, narg); \
+ } \
+ \
+ /* Prevent implicit conversion from string. */ \
+ luaL_checktype(L, narg, LUA_TNUMBER); \
+ double n = lua_tonumber(L, narg); \
+ \
+ ctype i = (ctype)n; \
+ if ((double)i != n) { \
+ /* double -> ctype truncated or rounded. */ \
+ luaL_error(L, "number %f was not an integer or out of range for " #type, \
+ n); \
+ } \
+ return i; \
+ } \
+ void lupb_push##type(lua_State *L, ctype val) { \
+ /* TODO: push integer for Lua >= 5.3, 64-bit cdata for LuaJIT. */ \
+ /* This is lossy for some [u]int64 values, which isn't great, but */ \
+ /* crashing when we encounter these values seems worse. */ \
+ lua_pushnumber(L, val); \
+ }
+
+INTCHECK(int64, int64_t);
+INTCHECK(int32, int32_t);
+INTCHECK(uint64, uint64_t);
+INTCHECK(uint32, uint32_t);
-static uint32_t chkint32(lua_State *L, int narg, const char *name) {
- lua_Number n = lua_tonumber(L, narg);
- if (n > INT32_MAX || n < INT32_MIN || rint(n) != n)
- luaL_error(L, "Invalid %s", name);
- return n;
+double lupb_checkdouble(lua_State *L, int narg) {
+ // If we were being really hard-nosed here, we'd check whether the input was
+ // an integer that has no precise double representation. But doubles aren't
+ // generally expected to be exact like integers are, and worse this could
+ // cause data-dependent runtime errors: one run of the program could work fine
+ // because the integer calculations happened to be exactly representable in
+ // double, while the next could crash because of subtly different input.
+
+ luaL_checktype(L, narg, LUA_TNUMBER); // lua_tonumber() implicitly converts.
+ return lua_tonumber(L, narg);
}
-// Sets a fielddef default from the given Lua value.
-static void lupb_setdefault(lua_State *L, int narg, upb_fielddef *f) {
- if (upb_fielddef_type(f) == UPB_TYPE_BOOL) {
- upb_fielddef_setdefaultbool(f, chkbool(L, narg, "bool default"));
- } else {
- // Numeric type.
- lua_Number num = luaL_checknumber(L, narg);
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_INT32:
- case UPB_TYPE_ENUM:
- if (num > INT32_MAX || num < INT32_MIN || num != rint(num))
- luaL_error(L, "Cannot convert %f to 32-bit integer", num);
- upb_fielddef_setdefaultint32(f, num);
- break;
- case UPB_TYPE_INT64:
- if (num > INT64_MAX || num < INT64_MIN || num != rint(num))
- luaL_error(L, "Cannot convert %f to 64-bit integer", num);
- upb_fielddef_setdefaultint64(f, num);
- break;
- case UPB_TYPE_UINT32:
- if (num > UINT32_MAX || num < 0 || num != rint(num))
- luaL_error(L, "Cannot convert %f to unsigned 32-bit integer", num);
- upb_fielddef_setdefaultuint32(f, num);
- break;
- case UPB_TYPE_UINT64:
- if (num > UINT64_MAX || num < 0 || num != rint(num))
- luaL_error(L, "Cannot convert %f to unsigned 64-bit integer", num);
- upb_fielddef_setdefaultuint64(f, num);
- break;
- case UPB_TYPE_DOUBLE:
- if (num > DBL_MAX || num < -DBL_MAX) {
- // This could happen if lua_Number was long double.
- luaL_error(L, "Cannot convert %f to double", num);
- }
- upb_fielddef_setdefaultdouble(f, num);
- break;
- case UPB_TYPE_FLOAT:
- if (num > FLT_MAX || num < -FLT_MAX)
- luaL_error(L, "Cannot convert %f to float", num);
- upb_fielddef_setdefaultfloat(f, num);
- break;
- default: luaL_error(L, "invalid type");
- }
+float lupb_checkfloat(lua_State *L, int narg) {
+ // We don't worry about checking whether the input can be exactly converted to
+ // float -- see above.
+
+ luaL_checktype(L, narg, LUA_TNUMBER); // lua_tonumber() implicitly converts.
+ return lua_tonumber(L, narg);
+}
+
+void lupb_pushdouble(lua_State *L, double d) {
+ lua_pushnumber(L, d);
+}
+
+void lupb_pushfloat(lua_State *L, float d) {
+ lua_pushnumber(L, d);
+}
+
+static void lupb_checkval(lua_State *L, int narg, upb_fieldtype_t type) {
+ switch(type) {
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_ENUM:
+ lupb_checkint32(L, narg);
+ break;
+ case UPB_TYPE_INT64:
+ lupb_checkint64(L, narg);
+ break;
+ case UPB_TYPE_UINT32:
+ lupb_checkuint32(L, narg);
+ break;
+ case UPB_TYPE_UINT64:
+ lupb_checkuint64(L, narg);
+ break;
+ case UPB_TYPE_DOUBLE:
+ lupb_checkdouble(L, narg);
+ break;
+ case UPB_TYPE_FLOAT:
+ lupb_checkfloat(L, narg);
+ break;
+ case UPB_TYPE_BOOL:
+ lupb_checkbool(L, narg);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ lupb_checkstring(L, narg);
+ break;
+ case UPB_TYPE_MESSAGE:
+ lupb_assert(L, false);
}
}
@@ -132,6 +275,13 @@ void lupb_checkstatus(lua_State *L, upb_status *s) {
}
}
+static upb_fieldtype_t lupb_checkfieldtype(lua_State *L, int narg) {
+ int type = luaL_checkint(L, narg);
+ if (!upb_fielddef_checktype(type))
+ luaL_argerror(L, narg, "invalid field type");
+ return type;
+}
+
#define CHK(pred) do { \
upb_status status = UPB_STATUS_INIT; \
pred; \
@@ -139,21 +289,28 @@ void lupb_checkstatus(lua_State *L, upb_status *s) {
} while (0)
-/* refcounted *****************************************************************/
+/* lupb_refcounted ************************************************************/
-// All upb objects that use upb_refcounted share a common Lua userdata
-// representation and a common scheme for caching Lua wrapper object. They do
-// however have different metatables. Objects are cached in a weak table
-// indexed by the C pointer of the object they are caching.
+// All upb objects that use upb_refcounted have a userdata that begins with a
+// pointer to that object. Each type has its own metatable. Objects are cached
+// in a weak table indexed by the C pointer of the object they are caching.
+//
+// Note that we consistently use memcpy() to read to/from the object. This
+// allows the userdata to use its own struct without violating aliasing, as
+// long as it begins with a pointer.
-typedef union {
- const upb_refcounted *refcounted;
- const upb_def *def;
- upb_symtab *symtab;
-} lupb_refcounted;
+// Checks type; if it matches, pulls the pointer out of the wrapper.
+void *lupb_refcounted_check(lua_State *L, int narg, const char *type) {
+ void *ud = luaL_checkudata(L, narg, type);
+ void *ret;
+ memcpy(&ret, ud, sizeof ret);
+ if (!ret) luaL_error(L, "called into dead object");
+ return ret;
+}
-static bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
- const char *type, const void *owner) {
+bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
+ const char *type, const void *ref_donor,
+ size_t size) {
if (obj == NULL) {
lua_pushnil(L);
return false;
@@ -161,30 +318,44 @@ static bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
// Lookup our cache in the registry (we don't put our objects in the registry
// directly because we need our cache to be a weak table).
- lupb_refcounted *ud = NULL;
lua_getfield(L, LUA_REGISTRYINDEX, LUPB_OBJCACHE);
assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb.
lua_pushlightuserdata(L, (void*)obj);
lua_rawget(L, -2);
- // Stack: objcache, cached value.
- bool create = lua_isnil(L, -1) ||
- // A corner case: it is possible for the value to be GC'd
- // already, in which case we should evict this entry and create
- // a new one.
- ((lupb_refcounted*)lua_touserdata(L, -1))->refcounted == NULL;
+ // Stack is now: objcache, cached value.
+
+ bool create = false;
+
+ if (lua_isnil(L, -1)) {
+ create = true;
+ } else {
+ void *ud = lua_touserdata(L, -1);
+ lupb_assert(L, ud);
+ void *ud_obj;
+ memcpy(&ud_obj, ud, sizeof(void*));
+
+ // A corner case: it is possible for the value to be GC'd
+ // already, in which case we should evict this entry and create
+ // a new one.
+ if (ud_obj == NULL) {
+ create = true;
+ }
+ }
+
+ void *ud = NULL;
+
if (create) {
// Remove bad cached value and push new value.
lua_pop(L, 1);
- // We take advantage of the fact that all of our objects are currently a
- // single pointer, and thus have the same layout.
- // TODO: this probably violates aliasing.
- ud = lua_newuserdata(L, sizeof(lupb_refcounted));
- ud->refcounted = obj;
- upb_refcounted_donateref(obj, owner, ud);
+ // All of our userdata begin with a pointer to the obj.
+ ud = lua_newuserdata(L, size);
+ memcpy(ud, &obj, sizeof(void*));
+ upb_refcounted_donateref(obj, ref_donor, ud);
luaL_getmetatable(L, type);
- assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb.
+ // Should have been created by luaopen_upb.
+ lupb_assert(L, !lua_isnil(L, -1));
lua_setmetatable(L, -2);
// Set it in the cache.
@@ -195,67 +366,111 @@ static bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
// Existing wrapper obj already has a ref.
ud = lua_touserdata(L, -1);
upb_refcounted_checkref(obj, ud);
- if (owner)
- upb_refcounted_unref(obj, owner);
+ if (ref_donor)
+ upb_refcounted_unref(obj, ref_donor);
}
+
lua_insert(L, -2);
lua_pop(L, 1);
return create;
}
-static void lupb_refcounted_pushnewrapper(lua_State *L, upb_refcounted *obj,
- const char *type, const void *owner) {
- bool created = lupb_refcounted_pushwrapper(L, obj, type, owner);
+void lupb_refcounted_pushnewrapper(lua_State *L, const upb_refcounted *obj,
+ const char *type, const void *ref_donor) {
+ bool created =
+ lupb_refcounted_pushwrapper(L, obj, type, ref_donor, sizeof(void *));
UPB_ASSERT_VAR(created, created == true);
}
+static int lupb_refcounted_gc(lua_State *L) {
+ void *ud = lua_touserdata(L, 1);
+ upb_refcounted *obj;
+ memcpy(&obj, ud, sizeof obj);
+ upb_refcounted_unref(obj, ud);
+
+ // Zero out pointer so we can detect a call into a GC'd object.
+ void *nullp = NULL;
+ memcpy(ud, &nullp, sizeof nullp);
+
+ return 0;
+}
+
+static const struct luaL_Reg lupb_refcounted_mm[] = {
+ {"__gc", lupb_refcounted_gc},
+ {NULL, NULL}
+};
+
/* lupb_def *******************************************************************/
static const upb_def *lupb_def_check(lua_State *L, int narg) {
- lupb_refcounted *r = luaL_testudata(L, narg, LUPB_MSGDEF);
- if (!r) r = luaL_testudata(L, narg, LUPB_ENUMDEF);
- if (!r) r = luaL_testudata(L, narg, LUPB_FIELDDEF);
- if (!r) luaL_typerror(L, narg, "upb def");
- if (!r->refcounted) luaL_error(L, "called into dead def");
- return r->def;
+ void *ud = luaL_testudata(L, narg, LUPB_MSGDEF);
+ if (!ud) ud = luaL_testudata(L, narg, LUPB_ENUMDEF);
+ if (!ud) ud = luaL_testudata(L, narg, LUPB_FIELDDEF);
+ if (!ud) luaL_typerror(L, narg, "upb def");
+
+ upb_def *ret;
+ memcpy(&ret, ud, sizeof ret);
+ if (!ret) luaL_error(L, "called into dead object");
+ return ret;
}
static upb_def *lupb_def_checkmutable(lua_State *L, int narg) {
const upb_def *def = lupb_def_check(L, narg);
if (upb_def_isfrozen(def))
- luaL_typerror(L, narg, "not allowed on frozen value");
+ luaL_error(L, "not allowed on frozen value");
return (upb_def*)def;
}
-bool lupb_def_pushwrapper(lua_State *L, const upb_def *def, const void *owner) {
+bool lupb_def_pushwrapper(lua_State *L, const upb_def *def,
+ const void *ref_donor) {
if (def == NULL) {
lua_pushnil(L);
return false;
}
const char *type = NULL;
- switch (def->type) {
- case UPB_DEF_MSG: type = LUPB_MSGDEF; break;
+ size_t size = sizeof(void*);
+
+ switch (upb_def_type(def)) {
+ case UPB_DEF_MSG: {
+ type = LUPB_MSGDEF;
+ size = lupb_msgdef_sizeof();
+ break;
+ }
case UPB_DEF_ENUM: type = LUPB_ENUMDEF; break;
case UPB_DEF_FIELD: type = LUPB_FIELDDEF; break;
default: luaL_error(L, "unknown deftype %d", def->type);
}
- return lupb_refcounted_pushwrapper(L, UPB_UPCAST(def), type, owner);
+
+ bool created =
+ lupb_refcounted_pushwrapper(L, UPB_UPCAST(def), type, ref_donor, size);
+
+ if (created && upb_def_type(def) == UPB_DEF_MSG) {
+ lupb_msgdef_init(L);
+ }
+
+ return created;
}
void lupb_def_pushnewrapper(lua_State *L, const upb_def *def,
- const void *owner) {
- bool created = lupb_def_pushwrapper(L, def, owner);
+ const void *ref_donor) {
+ bool created = lupb_def_pushwrapper(L, def, ref_donor);
UPB_ASSERT_VAR(created, created == true);
}
static int lupb_def_type(lua_State *L) {
const upb_def *def = lupb_def_check(L, 1);
- lua_pushnumber(L, upb_def_type(def));
+ lua_pushinteger(L, upb_def_type(def));
return 1;
}
+static int lupb_def_freeze(lua_State *L) {
+ upb_def *def = lupb_def_checkmutable(L, 1);
+ CHK(upb_def_freeze(&def, 1, &status));
+ return 0;
+}
+
static int lupb_def_isfrozen(lua_State *L) {
const upb_def *def = lupb_def_check(L, 1);
lua_pushboolean(L, upb_def_isfrozen(def));
@@ -269,234 +484,49 @@ static int lupb_def_fullname(lua_State *L) {
}
static int lupb_def_setfullname(lua_State *L) {
- CHK(upb_def_setfullname(lupb_def_checkmutable(L, 1), chkname(L, 2), &status));
+ const char *name = lupb_checkname(L, 2);
+ CHK(upb_def_setfullname(lupb_def_checkmutable(L, 1), name, &status));
return 0;
}
#define LUPB_COMMON_DEF_METHODS \
{"def_type", lupb_def_type}, \
{"full_name", lupb_def_fullname}, \
+ {"freeze", lupb_def_freeze}, \
{"is_frozen", lupb_def_isfrozen}, \
{"set_full_name", lupb_def_setfullname}, \
/* lupb_fielddef **************************************************************/
-static const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
- lupb_refcounted *r = luaL_checkudata(L, narg, LUPB_FIELDDEF);
- if (!r) luaL_typerror(L, narg, "upb fielddef");
- if (!r->refcounted) luaL_error(L, "called into dead fielddef");
- return upb_downcast_fielddef(r->def);
+const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
+ return lupb_refcounted_check(L, narg, LUPB_FIELDDEF);
}
static upb_fielddef *lupb_fielddef_checkmutable(lua_State *L, int narg) {
const upb_fielddef *f = lupb_fielddef_check(L, narg);
if (upb_fielddef_isfrozen(f))
- luaL_typerror(L, narg, "not allowed on frozen value");
+ luaL_error(L, "not allowed on frozen value");
return (upb_fielddef*)f;
}
-// Setter functions; these are called by both the constructor and the individual
-// setter API calls like field:set_type().
-
-static void lupb_fielddef_dosetdefault(lua_State *L, upb_fielddef *f,
- int narg) {
- int type = lua_type(L, narg);
- upb_fieldtype_t upbtype = upb_fielddef_type(f);
- if (type == LUA_TSTRING) {
- if (!upb_fielddef_isstring(f) && upbtype != UPB_TYPE_ENUM)
- luaL_argerror(L, narg, "field does not expect a string default");
- size_t len;
- const char *str = lua_tolstring(L, narg, &len);
- CHK(upb_fielddef_setdefaultstr(f, str, len, &status));
- } else {
- lupb_setdefault(L, narg, f);
- }
-}
-
-static void lupb_fielddef_dosetisextension(lua_State *L, upb_fielddef *f,
- int narg) {
- CHK(upb_fielddef_setisextension(f, chkbool(L, narg, "is_extension")));
-}
-
-static void lupb_fielddef_dosetlabel(lua_State *L, upb_fielddef *f, int narg) {
- int label = luaL_checkint(L, narg);
- if (!upb_fielddef_checklabel(label))
- luaL_argerror(L, narg, "invalid field label");
- upb_fielddef_setlabel(f, label);
-}
-
-static void lupb_fielddef_dosetlazy(lua_State *L, upb_fielddef *f, int narg) {
- upb_fielddef_setlazy(f, chkbool(L, narg, "lazy"));
-}
-
-static void lupb_fielddef_dosetname(lua_State *L, upb_fielddef *f, int narg) {
- CHK(upb_fielddef_setname(f, chkname(L, narg), &status));
-}
-
-static void lupb_fielddef_dosetnumber(lua_State *L, upb_fielddef *f, int narg) {
- CHK(upb_fielddef_setnumber(f, luaL_checkint(L, narg), &status));
-}
-
-static void lupb_fielddef_dosetsubdef(lua_State *L, upb_fielddef *f, int narg) {
- const upb_def *def = NULL;
- if (!lua_isnil(L, narg))
- def = lupb_def_check(L, narg);
- CHK(upb_fielddef_setsubdef(f, def, &status));
-}
-
-static void lupb_fielddef_dosetsubdefname(lua_State *L, upb_fielddef *f,
- int narg) {
- const char *name = NULL;
- if (!lua_isnil(L, narg))
- name = chkname(L, narg);
- CHK(upb_fielddef_setsubdefname(f, name, &status));
-}
-
-static void lupb_fielddef_dosetcontainingtypename(lua_State *L, upb_fielddef *f,
- int narg) {
- const char *name = NULL;
- if (!lua_isnil(L, narg))
- name = chkname(L, narg);
- CHK(upb_fielddef_setcontainingtypename(f, name, &status));
-}
-
-static void lupb_fielddef_dosettype(lua_State *L, upb_fielddef *f, int narg) {
- int type = luaL_checkint(L, narg);
- if (!upb_fielddef_checktype(type))
- luaL_argerror(L, narg, "invalid field type");
- upb_fielddef_settype(f, type);
-}
-
-static void lupb_fielddef_dosetintfmt(lua_State *L, upb_fielddef *f, int narg) {
- int32_t intfmt = luaL_checknumber(L, narg);
- if (!upb_fielddef_checkintfmt(intfmt))
- luaL_argerror(L, narg, "invalid intfmt");
- upb_fielddef_setintfmt(f, intfmt);
-}
-
-static void lupb_fielddef_dosettagdelim(lua_State *L, upb_fielddef *f,
- int narg) {
- CHK(upb_fielddef_settagdelim(f, chkbool(L, narg, "tagdelim")));
-}
-
-// Setter API calls. These use the setter functions above.
-
-static int lupb_fielddef_setcontainingtypename(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetcontainingtypename(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setdefault(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetdefault(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setisextension(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetisextension(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setlabel(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetlabel(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setlazy(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetlazy(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setname(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetname(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setnumber(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetnumber(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setsubdef(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetsubdef(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setsubdefname(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetsubdefname(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_settype(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosettype(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_setintfmt(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosetintfmt(L, f, 2);
- return 0;
-}
-
-static int lupb_fielddef_settagdelim(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lupb_fielddef_dosettagdelim(L, f, 2);
- return 0;
-}
-
-// Constructor and other methods.
-
static int lupb_fielddef_new(lua_State *L) {
upb_fielddef *f = upb_fielddef_new(&f);
- int narg = lua_gettop(L);
-
lupb_def_pushnewrapper(L, UPB_UPCAST(f), &f);
+ return 1;
+}
- if (narg == 0) return 1;
-
- // User can specify initialization values like so:
- // upb.FieldDef{label=upb.LABEL_REQUIRED, name="my_field", number=5,
- // type=upb.TYPE_INT32, default_value=12, type_name="Foo"}
- luaL_checktype(L, 1, LUA_TTABLE);
- for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)) {
- luaL_checktype(L, -2, LUA_TSTRING);
- const char *key = lua_tostring(L, -2);
- int v = -1;
- if (streql(key, "name")) lupb_fielddef_dosetname(L, f, v);
- else if (streql(key, "number")) lupb_fielddef_dosetnumber(L, f, v);
- else if (streql(key, "type")) lupb_fielddef_dosettype(L, f, v);
- else if (streql(key, "label")) lupb_fielddef_dosetlabel(L, f, v);
- else if (streql(key, "lazy")) lupb_fielddef_dosetlazy(L, f, v);
- else if (streql(key, "is_extension"))
- lupb_fielddef_dosetisextension(L, f, v);
- else if (streql(key, "containing_type_name"))
- lupb_fielddef_dosetcontainingtypename(L, f, v);
- else if (streql(key, "default_value")) ; // Defer to second pass.
- else if (streql(key, "subdef")) ; // Defer to second pass.
- else if (streql(key, "subdef_name")) ; // Defer to second pass.
- else luaL_error(L, "Cannot set fielddef member '%s'", key);
- }
+// Getters
- // Have to do these in a second pass because these depend on the type, so we
- // have to make sure the type is set if the user specified one.
- for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)) {
- const char *key = lua_tostring(L, -2);
- int v = -1;
- if (streql(key, "default_value")) lupb_fielddef_dosetdefault(L, f, v);
- else if (streql(key, "subdef")) lupb_fielddef_dosetsubdef(L, f, v);
- else if (streql(key, "subdef_name")) lupb_fielddef_dosetsubdefname(L, f, v);
- }
+static int lupb_fielddef_containingtype(lua_State *L) {
+ const upb_fielddef *f = lupb_fielddef_check(L, 1);
+ lupb_def_pushwrapper(L, UPB_UPCAST(upb_fielddef_containingtype(f)), NULL);
+ return 1;
+}
+static int lupb_fielddef_containingtypename(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ lua_pushstring(L, upb_fielddef_containingtypename(f));
return 1;
}
@@ -505,13 +535,13 @@ static int lupb_fielddef_default(lua_State *L) {
switch (upb_fielddef_type(f)) {
case UPB_TYPE_INT32:
int32:
- lua_pushnumber(L, upb_fielddef_defaultint32(f)); break;
+ lupb_pushint32(L, upb_fielddef_defaultint32(f)); break;
case UPB_TYPE_INT64:
- lua_pushnumber(L, upb_fielddef_defaultint64(f)); break;
+ lupb_pushint64(L, upb_fielddef_defaultint64(f)); break;
case UPB_TYPE_UINT32:
- lua_pushnumber(L, upb_fielddef_defaultuint32(f)); break;
+ lupb_pushuint32(L, upb_fielddef_defaultuint32(f)); break;
case UPB_TYPE_UINT64:
- lua_pushnumber(L, upb_fielddef_defaultuint64(f)); break;
+ lupb_pushuint64(L, upb_fielddef_defaultuint64(f)); break;
case UPB_TYPE_DOUBLE:
lua_pushnumber(L, upb_fielddef_defaultdouble(f)); break;
case UPB_TYPE_FLOAT:
@@ -519,11 +549,17 @@ static int lupb_fielddef_default(lua_State *L) {
case UPB_TYPE_BOOL:
lua_pushboolean(L, upb_fielddef_defaultbool(f)); break;
case UPB_TYPE_ENUM:
- if (!upb_fielddef_default_is_symbolic(f))
+ if (upb_fielddef_enumhasdefaultstr(f)) {
+ goto str;
+ } else if (upb_fielddef_enumhasdefaultint32(f)) {
goto int32;
- // Fallthrough.
+ } else {
+ lua_pushnil(L);
+ }
+ break;
case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES: {
+ case UPB_TYPE_BYTES:
+ str: {
size_t len;
const char *data = upb_fielddef_defaultstr(f, &len);
lua_pushlstring(L, data, len);
@@ -539,64 +575,68 @@ static int lupb_fielddef_getsel(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
upb_selector_t sel;
if (upb_handlers_getselector(f, luaL_checknumber(L, 2), &sel)) {
- lua_pushnumber(L, sel);
+ lua_pushinteger(L, sel);
return 1;
} else {
return 0;
}
}
-static int lupb_fielddef_label(lua_State *L) {
+static int lupb_fielddef_hassubdef(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushnumber(L, upb_fielddef_label(f));
+ lua_pushboolean(L, upb_fielddef_hassubdef(f));
return 1;
}
-static int lupb_fielddef_lazy(lua_State *L) {
+static int lupb_fielddef_index(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushboolean(L, upb_fielddef_lazy(f));
+ lua_pushinteger(L, upb_fielddef_index(f));
return 1;
}
-static int lupb_fielddef_name(lua_State *L) {
+static int lupb_fielddef_intfmt(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushstring(L, upb_fielddef_name(f));
+ lua_pushinteger(L, upb_fielddef_intfmt(f));
return 1;
}
-static int lupb_fielddef_number(lua_State *L) {
+static int lupb_fielddef_isextension(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- int32_t num = upb_fielddef_number(f);
- if (num)
- lua_pushnumber(L, num);
- else
- lua_pushnil(L);
+ lua_pushboolean(L, upb_fielddef_isextension(f));
return 1;
}
-static int lupb_fielddef_selectorbase(lua_State *L) {
+static int lupb_fielddef_istagdelim(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- if (!upb_fielddef_isfrozen(f))
- luaL_error(L, "_selectorbase is only defined for frozen fielddefs");
- lua_pushnumber(L, f->selector_base);
+ lua_pushboolean(L, upb_fielddef_istagdelim(f));
return 1;
}
-static int lupb_fielddef_hassubdef(lua_State *L) {
+static int lupb_fielddef_label(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushboolean(L, upb_fielddef_hassubdef(f));
+ lua_pushinteger(L, upb_fielddef_label(f));
return 1;
}
-static int lupb_fielddef_containingtype(lua_State *L) {
+static int lupb_fielddef_lazy(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lupb_def_pushwrapper(L, UPB_UPCAST(upb_fielddef_containingtype(f)), NULL);
+ lua_pushboolean(L, upb_fielddef_lazy(f));
return 1;
}
-static int lupb_fielddef_containingtypename(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lua_pushstring(L, upb_fielddef_containingtypename(f));
+static int lupb_fielddef_name(lua_State *L) {
+ const upb_fielddef *f = lupb_fielddef_check(L, 1);
+ lua_pushstring(L, upb_fielddef_name(f));
+ return 1;
+}
+
+static int lupb_fielddef_number(lua_State *L) {
+ const upb_fielddef *f = lupb_fielddef_check(L, 1);
+ int32_t num = upb_fielddef_number(f);
+ if (num)
+ lua_pushinteger(L, num);
+ else
+ lua_pushnil(L);
return 1;
}
@@ -620,43 +660,147 @@ static int lupb_fielddef_subdefname(lua_State *L) {
static int lupb_fielddef_type(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
if (upb_fielddef_typeisset(f))
- lua_pushnumber(L, upb_fielddef_type(f));
+ lua_pushinteger(L, upb_fielddef_type(f));
else
lua_pushnil(L);
return 1;
}
-static int lupb_fielddef_index(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushnumber(L, upb_fielddef_index(f));
- return 1;
+// Setters
+
+static int lupb_fielddef_setcontainingtypename(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ const char *name = NULL;
+ if (!lua_isnil(L, 2))
+ name = lupb_checkname(L, 2);
+ CHK(upb_fielddef_setcontainingtypename(f, name, &status));
+ return 0;
}
-static int lupb_fielddef_intfmt(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushnumber(L, upb_fielddef_intfmt(f));
- return 1;
+static int lupb_fielddef_setdefault(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT32:
+ upb_fielddef_setdefaultint32(f, lupb_checkint32(L, 2));
+ break;
+ case UPB_TYPE_INT64:
+ upb_fielddef_setdefaultint64(f, lupb_checkint64(L, 2));
+ break;
+ case UPB_TYPE_UINT32:
+ upb_fielddef_setdefaultuint32(f, lupb_checkuint32(L, 2));
+ break;
+ case UPB_TYPE_UINT64:
+ upb_fielddef_setdefaultuint64(f, lupb_checkuint64(L, 2));
+ break;
+ case UPB_TYPE_DOUBLE:
+ upb_fielddef_setdefaultdouble(f, lupb_checkdouble(L, 2));
+ break;
+ case UPB_TYPE_FLOAT:
+ upb_fielddef_setdefaultfloat(f, lupb_checkfloat(L, 2));
+ break;
+ case UPB_TYPE_BOOL:
+ upb_fielddef_setdefaultbool(f, lupb_checkbool(L, 2));
+ break;
+ case UPB_TYPE_MESSAGE:
+ return luaL_error(L, "Message types cannot have defaults.");
+ case UPB_TYPE_ENUM:
+ if (lua_type(L, 2) != LUA_TSTRING) {
+ upb_fielddef_setdefaultint32(f, lupb_checkint32(L, 2));
+ break;
+ }
+ // Else fall through and set string default.
+ case UPB_TYPE_BYTES:
+ case UPB_TYPE_STRING: {
+ size_t len;
+ const char *str = lua_tolstring(L, 2, &len);
+ CHK(upb_fielddef_setdefaultstr(f, str, len, &status));
+ }
+ }
+ return 0;
}
-static int lupb_fielddef_isextension(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushboolean(L, upb_fielddef_isextension(f));
- return 1;
+static int lupb_fielddef_setisextension(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ CHK(upb_fielddef_setisextension(f, lupb_checkbool(L, 2)));
+ return 0;
}
-static int lupb_fielddef_istagdelim(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushboolean(L, upb_fielddef_istagdelim(f));
- return 1;
+static int lupb_fielddef_setlabel(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ int label = luaL_checkint(L, 2);
+ if (!upb_fielddef_checklabel(label))
+ luaL_argerror(L, 2, "invalid field label");
+ upb_fielddef_setlabel(f, label);
+ return 0;
+}
+
+static int lupb_fielddef_setlazy(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ upb_fielddef_setlazy(f, lupb_checkbool(L, 2));
+ return 0;
+}
+
+static int lupb_fielddef_setname(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ CHK(upb_fielddef_setname(f, lupb_checkname(L, 2), &status));
+ return 0;
+}
+
+static int lupb_fielddef_setnumber(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ CHK(upb_fielddef_setnumber(f, luaL_checkint(L, 2), &status));
+ return 0;
+}
+
+static int lupb_fielddef_setsubdef(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ const upb_def *def = NULL;
+ if (!lua_isnil(L, 2))
+ def = lupb_def_check(L, 2);
+ CHK(upb_fielddef_setsubdef(f, def, &status));
+ return 0;
+}
+
+static int lupb_fielddef_setsubdefname(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ const char *name = NULL;
+ if (!lua_isnil(L, 2))
+ name = lupb_checkname(L, 2);
+ CHK(upb_fielddef_setsubdefname(f, name, &status));
+ return 0;
+}
+
+static int lupb_fielddef_settype(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ upb_fielddef_settype(f, lupb_checkfieldtype(L, 2));
+ return 0;
+}
+
+static int lupb_fielddef_setintfmt(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ int32_t intfmt = luaL_checknumber(L, 2);
+ if (!upb_fielddef_checkintfmt(intfmt))
+ luaL_argerror(L, 2, "invalid intfmt");
+ upb_fielddef_setintfmt(f, intfmt);
+ return 0;
}
-static int lupb_fielddef_gc(lua_State *L) {
- lupb_refcounted *r = luaL_checkudata(L, 1, LUPB_FIELDDEF);
- upb_def_unref(r->def, r);
- r->refcounted = NULL;
+static int lupb_fielddef_settagdelim(lua_State *L) {
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
+ bool is_tag_delim = lupb_checkbool(L, 2);
+ CHK(upb_fielddef_settagdelim(f, is_tag_delim));
return 0;
}
+static int lupb_fielddef_selectorbase(lua_State *L) {
+ const upb_fielddef *f = lupb_fielddef_check(L, 1);
+ if (!upb_fielddef_isfrozen(f))
+ luaL_error(L, "_selectorbase is only defined for frozen fielddefs");
+ lua_pushinteger(L, f->selector_base);
+ return 1;
+}
+
static const struct luaL_Reg lupb_fielddef_m[] = {
LUPB_COMMON_DEF_METHODS
@@ -696,82 +840,64 @@ static const struct luaL_Reg lupb_fielddef_m[] = {
{NULL, NULL}
};
-static const struct luaL_Reg lupb_fielddef_mm[] = {
- {"__gc", lupb_fielddef_gc},
- {NULL, NULL}
-};
-
/* lupb_msgdef ****************************************************************/
+typedef struct {
+ const upb_msgdef *md;
+
+ // These members are initialized lazily the first time a message is created
+ // for this def.
+ uint16_t *field_offsets;
+ size_t msg_size;
+ size_t hasbits_size;
+ lua_State *L;
+} lupb_msgdef;
+
+static size_t lupb_msgdef_sizeof() {
+ return sizeof(lupb_msgdef);
+}
+
const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg) {
- lupb_refcounted *r = luaL_checkudata(L, narg, LUPB_MSGDEF);
- if (!r) luaL_typerror(L, narg, LUPB_MSGDEF);
- if (!r->refcounted) luaL_error(L, "called into dead msgdef");
- return upb_downcast_msgdef(r->def);
+ return lupb_refcounted_check(L, narg, LUPB_MSGDEF);
+}
+
+lupb_msgdef *lupb_msgdef_check2(lua_State *L, int narg) {
+ return luaL_checkudata(L, narg, LUPB_MSGDEF);
}
static upb_msgdef *lupb_msgdef_checkmutable(lua_State *L, int narg) {
const upb_msgdef *m = lupb_msgdef_check(L, narg);
if (upb_msgdef_isfrozen(m))
- luaL_typerror(L, narg, "not allowed on frozen value");
+ luaL_error(L, "not allowed on frozen value");
return (upb_msgdef*)m;
}
-static int lupb_msgdef_gc(lua_State *L) {
- lupb_refcounted *r = luaL_checkudata(L, 1, LUPB_MSGDEF);
- upb_def_unref(r->def, r);
- r->refcounted = NULL;
- return 0;
-}
-
static int lupb_msgdef_new(lua_State *L) {
- int narg = lua_gettop(L);
upb_msgdef *md = upb_msgdef_new(&md);
lupb_def_pushnewrapper(L, UPB_UPCAST(md), &md);
-
- if (narg == 0) return 1;
-
- // User can specify initialization values like so:
- // upb.MessageDef{full_name="MyMessage", extstart=8000, fields={...}}
- luaL_checktype(L, 1, LUA_TTABLE);
- for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)) {
- luaL_checktype(L, -2, LUA_TSTRING);
- const char *key = lua_tostring(L, -2);
-
- if (streql(key, "full_name")) { // full_name="MyMessage"
- CHK(upb_def_setfullname(UPB_UPCAST(md), chkname(L, -1), &status));
- } else if (streql(key, "fields")) { // fields={...}
- // Iterate over the list of fields.
- luaL_checktype(L, -1, LUA_TTABLE);
- for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, -1);
- CHK(upb_msgdef_addfield(md, f, NULL, &status));
- }
- } else {
- // TODO: extrange=
- luaL_error(L, "Unknown initializer key '%s'", key);
- }
- }
return 1;
}
+// Unlike other refcounted types we need a custom __gc so that we free our field
+// offsets.
+static int lupb_msgdef_gc(lua_State *L) {
+ lupb_refcounted_gc(L);
+ lupb_msgdef *lmd = luaL_checkudata(L, -1, LUPB_MSGDEF);
+ free(lmd->field_offsets);
+ return 0;
+}
+
+static void lupb_msgdef_init(lua_State *L) {
+ lupb_msgdef *lmd = luaL_checkudata(L, -1, LUPB_MSGDEF);
+ lmd->L = L;
+ lmd->field_offsets = NULL;
+}
+
static int lupb_msgdef_add(lua_State *L) {
upb_msgdef *m = lupb_msgdef_checkmutable(L, 1);
- luaL_checktype(L, 2, LUA_TTABLE);
- int n = lua_rawlen(L, 2);
- // TODO: add upb interface that lets us avoid this malloc/free.
- upb_fielddef **fields = malloc(n * sizeof(upb_fielddef*));
- for (int i = 0; i < n; i++) {
- lua_rawgeti(L, -1, i + 1);
- fields[i] = lupb_fielddef_checkmutable(L, -1);
- lua_pop(L, 1);
- }
-
- upb_status status = UPB_STATUS_INIT;
- upb_msgdef_addfields(m, fields, n, NULL, &status);
- free(fields);
- lupb_checkstatus(L, &status);
+ upb_fielddef *f = lupb_fielddef_checkmutable(L, 2);
+ CHK(upb_msgdef_addfield(m, f, NULL, &status));
return 0;
}
@@ -823,7 +949,9 @@ static int lupb_msgdef_fields(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
upb_msg_iter *i = lua_newuserdata(L, sizeof(upb_msg_iter));
upb_msg_begin(i, m);
- lua_pushcclosure(L, &lupb_msgiter_next, 1);
+ // Need to guarantee that the msgdef outlives the iter.
+ lua_pushvalue(L, 1);
+ lua_pushcclosure(L, &lupb_msgiter_next, 2);
return 1;
}
@@ -850,65 +978,27 @@ static const struct luaL_Reg lupb_msgdef_m[] = {
/* lupb_enumdef ***************************************************************/
const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg) {
- lupb_refcounted *r = luaL_checkudata(L, narg, LUPB_ENUMDEF);
- if (!r) luaL_typerror(L, narg, LUPB_ENUMDEF);
- if (!r->refcounted) luaL_error(L, "called into dead enumdef");
- return upb_downcast_enumdef(r->def);
+ return lupb_refcounted_check(L, narg, LUPB_ENUMDEF);
}
static upb_enumdef *lupb_enumdef_checkmutable(lua_State *L, int narg) {
const upb_enumdef *f = lupb_enumdef_check(L, narg);
if (upb_enumdef_isfrozen(f))
- luaL_typerror(L, narg, "not allowed on frozen value");
+ luaL_error(L, "not allowed on frozen value");
return (upb_enumdef*)f;
}
-static int lupb_enumdef_gc(lua_State *L) {
- lupb_refcounted *r = luaL_checkudata(L, 1, LUPB_ENUMDEF);
- upb_def_unref(r->def, r);
- r->refcounted = NULL;
- return 0;
-}
-
static int lupb_enumdef_new(lua_State *L) {
- int narg = lua_gettop(L);
upb_enumdef *e = upb_enumdef_new(&e);
lupb_def_pushnewrapper(L, UPB_UPCAST(e), &e);
-
- if (narg == 0) return 1;
-
- // User can specify initialization values like so:
- // upb.EnumDef{full_name="MyEnum",
- // values={
- // {"FOO_VALUE_1", 1},
- // {"FOO_VALUE_2", 2}
- // }
- // }
- luaL_checktype(L, 1, LUA_TTABLE);
- for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)) {
- luaL_checktype(L, -2, LUA_TSTRING);
- const char *key = lua_tostring(L, -2);
- if (streql(key, "values")) {
- for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
- lua_rawgeti(L, -1, 1);
- luaL_checktype(L, -1, LUA_TSTRING);
- const char *name = lua_tostring(L, -1);
- lua_rawgeti(L, -2, 2);
- CHK(upb_enumdef_addval(e, name, chkint32(L, -1, "value"), &status));
- lua_pop(L, 2); // The key/val we got from lua_rawgeti()
- }
- } else if (streql(key, "full_name")) {
- CHK(upb_def_setfullname(UPB_UPCAST(e), chkname(L, -1), &status));
- } else {
- luaL_error(L, "Unknown initializer key '%s'", key);
- }
- }
return 1;
}
static int lupb_enumdef_add(lua_State *L) {
upb_enumdef *e = lupb_enumdef_checkmutable(L, 1);
- CHK(upb_enumdef_addval(e, chkname(L, 2), chkint32(L, 3, "value"), &status));
+ const char *name = lupb_checkname(L, 2);
+ int32_t val = lupb_checkint32(L, 3);
+ CHK(upb_enumdef_addval(e, name, val, &status));
return 0;
}
@@ -923,11 +1013,13 @@ static int lupb_enumdef_value(lua_State *L) {
int type = lua_type(L, 2);
if (type == LUA_TNUMBER) {
// Pushes "nil" for a NULL pointer.
- lua_pushstring(L, upb_enumdef_iton(e, chkint32(L, 2, "value")));
+ int32_t key = lupb_checkint32(L, 2);
+ lua_pushstring(L, upb_enumdef_iton(e, key));
} else if (type == LUA_TSTRING) {
+ const char *key = lua_tostring(L, 2);
int32_t num;
- if (upb_enumdef_ntoi(e, lua_tostring(L, 2), &num)) {
- lua_pushnumber(L, num);
+ if (upb_enumdef_ntoi(e, key, &num)) {
+ lua_pushinteger(L, num);
} else {
lua_pushnil(L);
}
@@ -943,7 +1035,7 @@ static int lupb_enumiter_next(lua_State *L) {
upb_enum_iter *i = lua_touserdata(L, lua_upvalueindex(1));
if (upb_enum_done(i)) return 0;
lua_pushstring(L, upb_enum_iter_name(i));
- lua_pushnumber(L, upb_enum_iter_number(i));
+ lua_pushinteger(L, upb_enum_iter_number(i));
upb_enum_next(i);
return 2;
}
@@ -952,12 +1044,13 @@ static int lupb_enumdef_values(lua_State *L) {
const upb_enumdef *e = lupb_enumdef_check(L, 1);
upb_enum_iter *i = lua_newuserdata(L, sizeof(upb_enum_iter));
upb_enum_begin(i, e);
- lua_pushcclosure(L, &lupb_enumiter_next, 1);
+ // Need to guarantee that the enumdef outlives the iter.
+ lua_pushvalue(L, 1);
+ lua_pushcclosure(L, &lupb_enumiter_next, 2);
return 1;
}
static const struct luaL_Reg lupb_enumdef_mm[] = {
- {"__gc", lupb_enumdef_gc},
{"__len", lupb_enumdef_len},
{NULL, NULL}
};
@@ -976,83 +1069,95 @@ static const struct luaL_Reg lupb_enumdef_m[] = {
// Inherits a ref on the symtab.
// Checks that narg is a proper lupb_symtab object. If it is, leaves its
// metatable on the stack for cache lookups/updates.
-upb_symtab *lupb_symtab_check(lua_State *L, int narg) {
- lupb_refcounted *r = luaL_checkudata(L, narg, LUPB_SYMTAB);
- if (!r) luaL_typerror(L, narg, LUPB_SYMTAB);
- if (!r->refcounted) luaL_error(L, "called into dead symtab");
- return r->symtab;
+const upb_symtab *lupb_symtab_check(lua_State *L, int narg) {
+ return lupb_refcounted_check(L, narg, LUPB_SYMTAB);
}
-// narg is a lua table containing a list of defs to add.
-void lupb_symtab_doadd(lua_State *L, upb_symtab *s, int narg) {
- luaL_checktype(L, narg, LUA_TTABLE);
- // Iterate over table twice. First iteration to count entries and
- // check constraints.
- int n = 0;
- for (lua_pushnil(L); lua_next(L, narg); lua_pop(L, 1)) {
- lupb_def_check(L, -1);
- ++n;
- }
+static upb_symtab *lupb_symtab_checkmutable(lua_State *L, int narg) {
+ const upb_symtab *s = lupb_symtab_check(L, narg);
+ if (upb_symtab_isfrozen(s))
+ luaL_error(L, "not allowed on frozen value");
+ return (upb_symtab*)s;
+}
- // Second iteration to build deflist and layout.
- upb_def **defs = malloc(n * sizeof(*defs));
- n = 0;
- for (lua_pushnil(L); lua_next(L, narg); lua_pop(L, 1)) {
- upb_def *def = lupb_def_checkmutable(L, -1);
- defs[n++] = def;
- }
+void lupb_symtab_pushwrapper(lua_State *L, const upb_symtab *s,
+ const void *ref_donor) {
+ lupb_refcounted_pushwrapper(L, UPB_UPCAST(s), LUPB_SYMTAB, ref_donor,
+ sizeof(void *));
+}
- upb_status status = UPB_STATUS_INIT;
- upb_symtab_add(s, defs, n, NULL, &status);
- free(defs);
- lupb_checkstatus(L, &status);
+void lupb_symtab_pushnewrapper(lua_State *L, const upb_symtab *s,
+ const void *ref_donor) {
+ lupb_refcounted_pushnewrapper(L, UPB_UPCAST(s), LUPB_SYMTAB, ref_donor);
}
static int lupb_symtab_new(lua_State *L) {
- int narg = lua_gettop(L);
upb_symtab *s = upb_symtab_new(&s);
- lupb_refcounted_pushnewrapper(L, UPB_UPCAST(s), LUPB_SYMTAB, &s);
- if (narg > 0) lupb_symtab_doadd(L, s, 1);
+ lupb_symtab_pushnewrapper(L, s, &s);
return 1;
}
-static int lupb_symtab_add(lua_State *L) {
- lupb_symtab_doadd(L, lupb_symtab_check(L, 1), 2);
+static int lupb_symtab_freeze(lua_State *L) {
+ upb_symtab_freeze(lupb_symtab_checkmutable(L, 1));
return 0;
}
-static int lupb_symtab_gc(lua_State *L) {
- lupb_refcounted *r = luaL_checkudata(L, 1, LUPB_SYMTAB);
- upb_symtab_unref(r->symtab, r);
- r->refcounted = NULL;
+static int lupb_symtab_isfrozen(lua_State *L) {
+ lua_pushboolean(L, upb_symtab_isfrozen(lupb_symtab_check(L, 1)));
+ return 1;
+}
+
+static int lupb_symtab_add(lua_State *L) {
+ upb_symtab *s = lupb_symtab_checkmutable(L, 1);
+ luaL_checktype(L, 2, LUA_TTABLE);
+ // Iterate over table twice. First iteration to count entries and
+ // check constraints.
+ int n = 0;
+ for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
+ lupb_def_checkmutable(L, -1);
+ ++n;
+ }
+
+ // Second iteration to build deflist.
+ // Allocate list with lua_newuserdata() so it is anchored as a GC root in
+ // case any Lua functions longjmp().
+ upb_def **defs = lua_newuserdata(L, n * sizeof(*defs));
+ n = 0;
+ for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
+ upb_def *def = lupb_def_checkmutable(L, -1);
+ defs[n++] = def;
+ }
+
+ CHK(upb_symtab_add(s, defs, n, NULL, &status));
return 0;
}
static int lupb_symtab_lookup(lua_State *L) {
- upb_symtab *s = lupb_symtab_check(L, 1);
+ const upb_symtab *s = lupb_symtab_check(L, 1);
for (int i = 2; i <= lua_gettop(L); i++) {
- const upb_def *def =
- upb_symtab_lookup(s, luaL_checkstring(L, i), &def);
- lupb_def_pushwrapper(L, def, &def);
+ const upb_def *def = upb_symtab_lookup(s, luaL_checkstring(L, i));
+ lupb_def_pushwrapper(L, def, NULL);
lua_replace(L, i);
}
return lua_gettop(L) - 1;
}
-static int lupb_symtab_getdefs(lua_State *L) {
- upb_symtab *s = lupb_symtab_check(L, 1);
- upb_deftype_t type = luaL_checkint(L, 2);
- int count;
- const upb_def **defs = upb_symtab_getdefs(s, type, &defs, &count);
+static int lupb_symtabiter_next(lua_State *L) {
+ upb_symtab_iter *i = lua_touserdata(L, lua_upvalueindex(1));
+ if (upb_symtab_done(i)) return 0;
+ lupb_def_pushwrapper(L, upb_symtab_iter_def(i), NULL);
+ upb_symtab_next(i);
+ return 1;
+}
- // Create the table in which we will return the defs.
- lua_createtable(L, count, 0);
- for (int i = 0; i < count; i++) {
- const upb_def *def = defs[i];
- lupb_def_pushwrapper(L, def, &defs);
- lua_rawseti(L, -2, i + 1);
- }
- free(defs);
+static int lupb_symtab_defs(lua_State *L) {
+ const upb_symtab *s = lupb_symtab_check(L, 1);
+ upb_deftype_t type = lua_gettop(L) > 1 ? luaL_checkint(L, 2) : UPB_DEF_ANY;
+ upb_symtab_iter *i = lua_newuserdata(L, sizeof(upb_symtab_iter));
+ upb_symtab_begin(i, s, type);
+ // Need to guarantee that the symtab outlives the iter.
+ lua_pushvalue(L, 1);
+ lua_pushcclosure(L, &lupb_symtabiter_next, 2);
return 1;
}
@@ -1061,7 +1166,7 @@ static int lupb_symtab_getdefs(lua_State *L) {
// the descriptor.proto schema and the protobuf binary format.
static int lupb_symtab_load_descriptor(lua_State *L) {
size_t len;
- upb_symtab *s = lupb_symtab_check(L, 1);
+ upb_symtab *s = lupb_symtab_checkmutable(L, 1);
const char *str = luaL_checklstring(L, 2, &len);
CHK(upb_load_descriptor_into_symtab(s, str, len, &status));
return 0;
@@ -1069,67 +1174,598 @@ static int lupb_symtab_load_descriptor(lua_State *L) {
static const struct luaL_Reg lupb_symtab_m[] = {
{"add", lupb_symtab_add},
- {"getdefs", lupb_symtab_getdefs},
+ {"defs", lupb_symtab_defs},
+ {"freeze", lupb_symtab_freeze},
+ {"is_frozen", lupb_symtab_isfrozen},
{"lookup", lupb_symtab_lookup},
{"load_descriptor", lupb_symtab_load_descriptor},
{NULL, NULL}
};
-static const struct luaL_Reg lupb_symtab_mm[] = {
- {"__gc", lupb_symtab_gc},
+
+/* lupb_array *****************************************************************/
+
+// A lupb_array provides a strongly-typed array.
+//
+// For the moment we store all values in the userdata's environment table /
+// userval, for simplicity. Later we may wish to move the data into raw
+// memory as both a space and time optimization.
+//
+// Compared to regular Lua tables:
+//
+// - we only allow integer indices.
+// - all entries must match the type of the table.
+// - we do not allow "holes" in the array; you can only assign to an existing
+// index or one past the end (which will grow the array by one).
+
+typedef struct {
+ uint32_t size;
+ upb_fieldtype_t type;
+ const upb_msgdef *msgdef; // Only when type == UPB_TYPE_MESSAGE
+} lupb_array;
+
+static lupb_array *lupb_array_check(lua_State *L, int narg) {
+ return luaL_checkudata(L, narg, LUPB_ARRAY);
+}
+
+static uint32_t lupb_array_checkindex(lua_State *L, int narg, uint32_t max) {
+ uint32_t n = lupb_checkuint32(L, narg);
+ if (n == 0 || n > max) { // Lua uses 1-based indexing. :(
+ luaL_error(L, "Invalid array index.");
+ }
+ return n;
+}
+
+static int lupb_array_new(lua_State *L) {
+ lupb_array *array = newudata_with_userval(L, sizeof(*array), LUPB_ARRAY);
+ array->size = 0;
+
+ if (lua_type(L, 1) == LUA_TNUMBER) {
+ array->type = lupb_checkfieldtype(L, 1);
+ if (array->type == UPB_TYPE_MESSAGE) {
+ return luaL_error(
+ L, "For message arrays construct with the specific message type.");
+ }
+ } else {
+ array->type = UPB_TYPE_MESSAGE;
+ array->msgdef = lupb_msgdef_check(L, 1);
+
+ // Store a reference to this msgdef in the environment table to ensure it
+ // outlives this array.
+ lua_getuservalue(L, -1);
+ lua_pushvalue(L, 1);
+ lua_rawseti(L, -2, 0);
+ lua_pop(L, 1); // Pop userval.
+ }
+
+ return 1;
+}
+
+static int lupb_array_newindex(lua_State *L) {
+ lupb_array *array = lupb_array_check(L, 1);
+ uint32_t n = lupb_array_checkindex(L, 2, array->size + 1);
+
+ if (n == array->size + 1) {
+ array->size++;
+ }
+
+ if (array->type == UPB_TYPE_MESSAGE) {
+ if (array->msgdef != lupb_msg_checkdef(L, 3)) {
+ return luaL_error(L, "Tried to assign wrong message type.");
+ }
+ } else {
+ lupb_checkval(L, 3, array->type);
+ }
+
+ // Write value to userval table.
+ lua_getuservalue(L, 1);
+ lua_pushvalue(L, 3);
+ lua_rawseti(L, -2, n);
+
+ return 0; // 1 for chained assignments?
+}
+
+static int lupb_array_index(lua_State *L) {
+ lupb_array *array = lupb_array_check(L, 1);
+ uint32_t n = lupb_array_checkindex(L, 2, array->size);
+
+ lua_getuservalue(L, 1);
+ lua_rawgeti(L, -1, n);
+ return 1;
+}
+
+static int lupb_array_len(lua_State *L) {
+ lupb_array *array = lupb_array_check(L, 1);
+ lua_pushnumber(L, array->size);
+ return 1;
+}
+
+static const struct luaL_Reg lupb_array_mm[] = {
+ {"__index", lupb_array_index},
+ {"__len", lupb_array_len},
+ {"__newindex", lupb_array_newindex},
+ {NULL, NULL}
+};
+
+/* lupb_msg **************************************************************/
+
+// A lupb_msg is a userdata where:
+//
+// - the userdata's memory contains hasbits and primitive fields.
+// - the userdata's environment table / uservalue contains references to string
+// fields, submessage fields, and array fields.
+
+typedef struct {
+ const lupb_msgdef *lmd;
+ char data[];
+} lupb_msg;
+
+#define MSGDEF_INDEX 0
+
+static bool in_userval(const upb_fielddef *f) {
+ return upb_fielddef_isseq(f) || upb_fielddef_issubmsg(f) ||
+ upb_fielddef_isstring(f);
+}
+
+static size_t lupb_sizeof(lua_State *L, const upb_fielddef *f) {
+ 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;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ case UPB_TYPE_MESSAGE:
+ lupb_assert(L, false);
+ return 0;
+ }
+}
+
+static int div_round_up(size_t n, size_t d) {
+ int ret = n / d;
+ // If there was a positive remainder, then the result was rounded down and we
+ // need to compensate by adding one.
+ if (n % d > 0) ++ret;
+ return ret;
+}
+
+static size_t align_up(size_t val, size_t align) {
+ return val % align == 0 ? val : val + align - (val % align);
+}
+
+// If we always read/write as a consistent type to each value, this shouldn't
+// violate aliasing.
+#define DEREF(msg, ofs, type) *(type*)(&msg->data[ofs])
+
+lupb_msg *lupb_msg_check(lua_State *L, int narg) {
+ lupb_msg *msg = luaL_checkudata(L, narg, LUPB_MSG);
+ if (!msg->lmd) luaL_error(L, "called into dead msg");
+ return msg;
+}
+
+const upb_msgdef *lupb_msg_checkdef(lua_State *L, int narg) {
+ return lupb_msg_check(L, narg)->lmd->md;
+}
+
+static const upb_fielddef *lupb_msg_checkfield(lua_State *L,
+ const lupb_msgdef *lmd,
+ int fieldarg) {
+ const char *fieldname = luaL_checkstring(L, fieldarg);
+ const upb_fielddef *f = upb_msgdef_ntof(lmd->md, fieldname);
+
+ if (!f) {
+ const char *msg = lua_pushfstring(L, "no such field: %s", fieldname);
+ luaL_argerror(L, fieldarg, msg);
+ return NULL; // Never reached.
+ }
+
+ return f;
+}
+
+// Assigns offsets for storing data in instances of messages for this type, if
+// they have not already been assigned. "narg" should be the stack location of
+// a Lua msgdef object. It should be frozen (if it is not, we will throw an
+// error). It should not throw errors in any other case, since we may have
+// values on our stack that would leak if we longjmp'd across them.
+//
+// TODO(haberman): (if we want to avoid this and be robust against even lua
+// errors due to OOM, we should stop using upb_handlers_newfrozen() and
+// implement it ourselves with a Lua table as cache, since that would get
+// cleaned up properly on error).
+static lupb_msgdef *lupb_msg_assignoffsets(lua_State *L, int narg) {
+ lupb_msgdef *lmd = lupb_msgdef_check2(L, narg);
+ if (!upb_msgdef_isfrozen(lmd->md))
+ luaL_error(L, "msgdef must be frozen");
+
+ if (lmd->field_offsets) {
+ // Already assigned.
+ return lmd;
+ }
+
+ int n = upb_msgdef_numfields(lmd->md);
+ uint16_t *offsets = malloc(sizeof(*offsets) * n);
+
+ // Offset with the raw data part; starts with hasbits.
+ size_t hasbits_size = div_round_up(n, 8);
+ size_t data_ofs = hasbits_size;
+ // Index within the userval.
+ // Starts at one to not collide with MSGDEF_INDEX.
+ size_t userval_idx = 1;
+
+ // Assign offsets.
+ upb_msg_iter i;
+ for (upb_msg_begin(&i, lmd->md); !upb_msg_done(&i); upb_msg_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ if (in_userval(f)) {
+ offsets[upb_fielddef_index(f)] = userval_idx++;
+ } else {
+ size_t size = lupb_sizeof(L, f);
+ data_ofs = align_up(data_ofs, size);
+ offsets[upb_fielddef_index(f)] = data_ofs;
+ data_ofs += size;
+ }
+ }
+
+ lmd->field_offsets = offsets;
+ lmd->msg_size = sizeof(lupb_msg) + data_ofs;
+ lmd->hasbits_size = hasbits_size;
+
+ // Now recursively assign offsets for all submessages, and also add them to
+ // the uservalue to ensure that all the lupb_msgdef objects for our
+ // submessages outlive us. This is particularly important if/when we build
+ // handlers to populate this msgdef.
+
+ lua_pushvalue(L, narg);
+ lua_newtable(L); // This will be our userval.
+
+ int idx = 1;
+ for (upb_msg_begin(&i, lmd->md); !upb_msg_done(&i); upb_msg_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
+ bool created = lupb_def_pushwrapper(L, upb_fielddef_subdef(f), NULL);
+ UPB_ASSERT_VAR(created, !created);
+ lupb_msg_assignoffsets(L, -1);
+ lua_rawseti(L, -2, idx++); // Append to uservalue.
+ }
+ }
+
+ lua_setuservalue(L, -2);
+ lua_pop(L, 1); // copy of msgdef
+
+ return lmd;
+}
+
+void lupb_msg_pushnew(lua_State *L, int narg) {
+ lupb_msgdef *lmd = lupb_msg_assignoffsets(L, narg);
+
+ // Add passed-in MessageDef to a table which will become the msg's userval.
+ lua_pushvalue(L, narg);
+ lua_newtable(L);
+ lua_pushvalue(L, narg);
+ lua_rawseti(L, -2, MSGDEF_INDEX);
+
+ lupb_msg *msg = newudata_with_userval(L, lmd->msg_size, LUPB_MSG);
+ memset(msg, 0, lmd->msg_size);
+
+ // Create a msg->msgdef reference, both:
+ // 1. a pointer in the userdata itself (for easy access) and
+ msg->lmd = lmd;
+
+ // 2. a reference in Lua-space from the msg's uservalue to the messagedef
+ // wrapper object (so the msgdef wrapper object will always outlive us,
+ // GC-wise).
+ lua_pushvalue(L, -2); // Push the table from before.
+ lua_setuservalue(L, -2); // Pop table, now msg is at top again.
+ lua_remove(L, -2); // Remove table, so new message is only new value.
+}
+
+static int lupb_msg_new(lua_State *L) {
+ lupb_msg_pushnew(L, 1);
+ return 1;
+}
+
+static bool lupb_msg_has(const lupb_msg *msg, const upb_fielddef *f) {
+ uint16_t idx = upb_fielddef_index(f);
+ return msg->data[idx / 8] & (1 << (idx % 8));
+}
+
+static void lupb_msg_set(lupb_msg *msg, const upb_fielddef *f) {
+ uint16_t idx = upb_fielddef_index(f);
+ msg->data[idx / 8] |= (1 << (idx % 8));
+}
+
+static int lupb_msg_index(lua_State *L) {
+ lupb_msg *msg = lupb_msg_check(L, 1);
+ const upb_fielddef *f = lupb_msg_checkfield(L, msg->lmd, 2);
+
+ if (!upb_fielddef_isseq(f) && !lupb_msg_has(msg, f)) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ int ofs = msg->lmd->field_offsets[upb_fielddef_index(f)];
+
+ if (in_userval(f)) {
+ lua_getuservalue(L, 1);
+ lua_pushinteger(L, ofs);
+ lua_rawget(L, -2);
+ } else {
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_FLOAT:
+ lupb_pushfloat(L, DEREF(msg, ofs, float));
+ break;
+ case UPB_TYPE_DOUBLE:
+ lupb_pushdouble(L, DEREF(msg, ofs, double));
+ break;
+ case UPB_TYPE_BOOL:
+ lua_pushboolean(L, DEREF(msg, ofs, bool));
+ break;
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT32:
+ lupb_pushint32(L, DEREF(msg, ofs, int32_t));
+ break;
+ case UPB_TYPE_UINT32:
+ lupb_pushuint32(L, DEREF(msg, ofs, uint32_t));
+ break;
+ case UPB_TYPE_INT64:
+ if (LUA_VERSION_NUM < 503) {
+ // Check value? Lua < 5.3.0 has no native integer support, lua_Number
+ // is probably double which can't exactly represent large int64s.
+ }
+ lupb_pushint64(L, DEREF(msg, ofs, int64_t));
+ break;
+ case UPB_TYPE_UINT64:
+ if (LUA_VERSION_NUM < 503) {
+ // Check value? Lua < 5.3.0 has no native integer support, lua_Number
+ // is probably double which can't exactly represent large uint64s.
+ }
+ lupb_pushuint64(L, DEREF(msg, ofs, uint64_t));
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ case UPB_TYPE_MESSAGE:
+ lupb_assert(L, false);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+int lupb_msg_newindex(lua_State *L) {
+ lupb_msg *msg = lupb_msg_check(L, 1);
+ const upb_fielddef *f = lupb_msg_checkfield(L, msg->lmd, 2);
+
+ lupb_msg_set(msg, f);
+
+ int ofs = msg->lmd->field_offsets[upb_fielddef_index(f)];
+
+ if (in_userval(f)) {
+ // Type-check and then store in the userval.
+ if (upb_fielddef_isseq(f)) {
+ lupb_array *array = lupb_array_check(L, 3);
+ if (array->type != upb_fielddef_type(f) ||
+ (array->type == UPB_TYPE_MESSAGE &&
+ array->msgdef != upb_fielddef_msgsubdef(f))) {
+ return luaL_error(L, "Array type mismatch");
+ }
+ } else if (upb_fielddef_isstring(f)) {
+ lupb_checkstring(L, 3);
+ } else {
+ if (lupb_msg_checkdef(L, 3) != upb_fielddef_msgsubdef(f)) {
+ return luaL_error(L, "Message type mismatch");
+ }
+ }
+ lua_getuservalue(L, 1);
+ lua_pushvalue(L, 3);
+ lua_rawseti(L, -2, ofs);
+ } else {
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_FLOAT:
+ DEREF(msg, ofs, float) = lupb_checkfloat(L, 3);
+ break;
+ case UPB_TYPE_DOUBLE:
+ DEREF(msg, ofs, double) = lupb_checkdouble(L, 3);
+ break;
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT32:
+ DEREF(msg, ofs, int32_t) = lupb_checkint32(L, 3);
+ break;
+ case UPB_TYPE_UINT32:
+ DEREF(msg, ofs, uint32_t) = lupb_checkuint32(L, 3);
+ break;
+ case UPB_TYPE_INT64:
+ DEREF(msg, ofs, int64_t) = lupb_checkint64(L, 3);
+ break;
+ case UPB_TYPE_UINT64:
+ DEREF(msg, ofs, uint64_t) = lupb_checkuint64(L, 3);
+ break;
+ case UPB_TYPE_BOOL:
+ DEREF(msg, ofs, bool) = lupb_checkbool(L, 3);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ case UPB_TYPE_MESSAGE:
+ lupb_assert(L, false);
+ }
+ }
+
+ return 0; // 1 for chained assignments?
+}
+
+static const struct luaL_Reg lupb_msg_mm[] = {
+ {"__index", lupb_msg_index},
+ {"__newindex", lupb_msg_newindex},
{NULL, NULL}
};
+/* lupb_msg populating handlers ***********************************************/
+
+// NOTE: doesn't support repeated or submessage fields yet. Coming soon.
+
+typedef struct {
+ uint32_t ofs;
+ uint32_t hasbit;
+} lupb_handlerdata;
+
+static void lupb_sethasbit(lupb_msg *msg, uint32_t hasbit) {
+ msg->data[hasbit / 8] |= 1 << (hasbit % 8);
+}
+
+static size_t strhandler(void *closure, const void *hd, const char *str,
+ size_t len, const upb_bufhandle *handle) {
+ lupb_msg *msg = closure;
+ const lupb_handlerdata *data = hd;
+ lua_State *L = msg->lmd->L;
+ lua_pushlstring(L, str, len);
+ lua_rawseti(L, -2, data->ofs);
+ lupb_sethasbit(msg, data->hasbit);
+ return len;
+}
+
+const void *newhandlerdata(upb_handlers *h, uint32_t ofs, uint32_t hasbit) {
+ lupb_handlerdata *data = malloc(sizeof(*data));
+ data->ofs = ofs;
+ data->hasbit = hasbit;
+ upb_handlers_addcleanup(h, data, free);
+ return data;
+}
+
+void callback(const void *closure, upb_handlers *h) {
+ lua_State *L = (lua_State*)closure;
+ lupb_def_pushwrapper(L, UPB_UPCAST(upb_handlers_msgdef(h)), NULL);
+ lupb_msgdef *lmd = lupb_msg_assignoffsets(L, -1);
+ upb_msg_iter i;
+ upb_msg_begin(&i, upb_handlers_msgdef(h));
+ for (; !upb_msg_done(&i); upb_msg_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ int hasbit = upb_fielddef_index(f);
+ uint16_t ofs = lmd->field_offsets[upb_fielddef_index(f)];
+ if (upb_fielddef_isseq(f)) {
+ luaL_error(L, "Doesn't support repeated fields yet.");
+ } else {
+ 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:
+ hasbit += offsetof(lupb_msg, data) * 8;
+ ofs += offsetof(lupb_msg, data);
+ upb_shim_set(h, f, ofs, hasbit);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES: {
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, ofs, hasbit));
+ // XXX: does't currently handle split buffers.
+ upb_handlers_setstring(h, f, strhandler, &attr);
+ upb_handlerattr_uninit(&attr);
+ break;
+ }
+ case UPB_TYPE_MESSAGE:
+ luaL_error(L, "Doesn't support submessages yet.");
+ break;
+ }
+ }
+ }
+ lua_pop(L, 1); // msgdef wrapper
+}
+
+const upb_handlers *lupb_msg_newwritehandlers(lua_State *L, int narg,
+ const void *owner) {
+ lupb_msgdef *lmd = lupb_msg_assignoffsets(L, narg);
+ return upb_handlers_newfrozen(lmd->md, owner, callback, L);
+}
+
+
/* lupb toplevel **************************************************************/
-static int lupb_def_freeze(lua_State *L) {
+static int lupb_freeze(lua_State *L) {
int n = lua_gettop(L);
- upb_def **defs = malloc(n * sizeof(upb_def*));
+ // Scratch memory; lua_newuserdata() anchors it as a GC root in case any Lua
+ // functions fail.
+ upb_def **defs = lua_newuserdata(L, n * sizeof(upb_def*));
for (int i = 0; i < n; i++) {
// Could allow an array of defs here also.
defs[i] = lupb_def_checkmutable(L, i + 1);
}
- upb_status s = UPB_STATUS_INIT;
- upb_def_freeze(defs, n, &s);
- free(defs);
- lupb_checkstatus(L, &s);
+ CHK(upb_def_freeze(defs, n, &status));
return 0;
}
static const struct luaL_Reg lupb_toplevel_m[] = {
+ {"Array", lupb_array_new},
{"EnumDef", lupb_enumdef_new},
{"FieldDef", lupb_fielddef_new},
+ {"Message", lupb_msg_new},
{"MessageDef", lupb_msgdef_new},
{"SymbolTable", lupb_symtab_new},
- {"freeze", lupb_def_freeze},
+ {"freeze", lupb_freeze},
{NULL, NULL}
};
-// Register the given type with the given methods and metamethods.
-static void lupb_register_type(lua_State *L, const char *name,
- const luaL_Reg *m, const luaL_Reg *mm) {
+void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
+ const luaL_Reg *mm, bool refcount_gc) {
luaL_newmetatable(L, name);
- lupb_setfuncs(L, mm); // Register all mm in the metatable.
- lua_createtable(L, 0, 0);
- // Methods go in the mt's __index method. This implies that you can't
- // implement __index.
- lupb_setfuncs(L, m);
- lua_setfield(L, -2, "__index");
+
+ if (mm) {
+ lupb_setfuncs(L, mm);
+ }
+
+ if (refcount_gc) {
+ lupb_setfuncs(L, lupb_refcounted_mm);
+ }
+
+ if (m) {
+ // Methods go in the mt's __index method. This implies that you can't
+ // implement __index and also have methods.
+ lua_getfield(L, -1, "__index");
+ lupb_assert(L, lua_isnil(L, -1));
+ lua_pop(L, 1);
+
+ lua_createtable(L, 0, 0);
+ lupb_setfuncs(L, m);
+ lua_setfield(L, -2, "__index");
+ }
+
lua_pop(L, 1); // The mt.
}
static void lupb_setfieldi(lua_State *L, const char *field, int i) {
- lua_pushnumber(L, i);
+ lua_pushinteger(L, i);
lua_setfield(L, -2, field);
}
int luaopen_upb(lua_State *L) {
- lupb_register_type(L, LUPB_MSGDEF, lupb_msgdef_m, lupb_msgdef_mm);
- lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm);
- lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, lupb_fielddef_mm);
- lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, lupb_symtab_mm);
+ static char module_key;
+ if (lupb_openlib(L, &module_key, "upb", lupb_toplevel_m)) {
+ return 1;
+ }
+
+ // Non-refcounted types.
+ lupb_register_type(L, LUPB_ARRAY, NULL, lupb_array_mm, false);
+ lupb_register_type(L, LUPB_MSG, NULL, lupb_msg_mm, false);
+
+ // Refcounted types.
+ lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm, true);
+ lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL, true);
+ lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, NULL, true);
+
+ // Refcounted but with custom __gc.
+ lupb_register_type(L, LUPB_MSGDEF, lupb_msgdef_m, lupb_msgdef_mm, false);
// Create our object cache.
lua_newtable(L);
@@ -1139,26 +1775,6 @@ int luaopen_upb(lua_State *L) {
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, LUPB_OBJCACHE);
- lupb_newlib(L, "upb", lupb_toplevel_m);
-
- // Define a couple functions as Lua source (kept here instead of a separate
- // Lua file so that upb.so is self-contained)
- const char *lua_source =
- "return function(upb)\n"
- " upb.build_defs = function(defs)\n"
- " local symtab = upb.SymbolTable(defs)\n"
- " return symtab:getdefs(upb.DEF_ANY)\n"
- " end\n"
- "end";
-
- if (luaL_dostring(L, lua_source) != 0)
- lua_error(L);
-
- // Call the chunk that will define the extra functions on upb, passing our
- // package dictionary as the argument.
- lua_pushvalue(L, -2);
- lua_call(L, 1, 0);
-
// Register constants.
lupb_setfieldi(L, "LABEL_OPTIONAL", UPB_LABEL_OPTIONAL);
lupb_setfieldi(L, "LABEL_REQUIRED", UPB_LABEL_REQUIRED);
@@ -1220,8 +1836,14 @@ int luaopen_upb(lua_State *L) {
lupb_setfieldi(L, "HANDLER_STARTSEQ", UPB_HANDLER_STARTSEQ);
lupb_setfieldi(L, "HANDLER_ENDSEQ", UPB_HANDLER_ENDSEQ);
+ // Call the chunk that will define the extra functions on upb, passing our
+ // package dictionary as the argument.
+ if (luaL_loadbuffer(L, upb_lua, sizeof(upb_lua), "upb.lua") ||
+ lua_pcall(L, 0, LUA_MULTRET, 0)) {
+ lua_error(L);
+ }
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 0);
+
return 1; // Return package table.
}
-
-// Alternate names so that the library can be loaded as upb5_1 etc.
-int LUPB_OPENFUNC(upb)(lua_State *L) { return luaopen_upb(L); }
diff --git a/upb/bindings/lua/upb.h b/upb/bindings/lua/upb.h
index e6b4f2f..99fe8fe 100644
--- a/upb/bindings/lua/upb.h
+++ b/upb/bindings/lua/upb.h
@@ -10,36 +10,120 @@
#ifndef UPB_LUA_UPB_H_
#define UPB_LUA_UPB_H_
+#include "lauxlib.h"
#include "upb/def.h"
+#include "upb/handlers.h"
+#include "upb/symtab.h"
// Lua 5.1/5.2 compatibility code.
#if LUA_VERSION_NUM == 501
#define lua_rawlen lua_objlen
-#define lupb_newlib(L, name, l) luaL_register(L, name, l)
-#define lupb_setfuncs(L, l) luaL_register(L, NULL, l)
-#define LUPB_OPENFUNC(mod) luaopen_ ## mod ## upb5_1
+
+// Lua >= 5.2's getuservalue/setuservalue functions do not exist in prior
+// versions but the older function lua_getfenv() can provide 100% of its
+// capabilities (the reverse is not true).
+#define lua_getuservalue(L, index) lua_getfenv(L, index)
+#define lua_setuservalue(L, index) lua_setfenv(L, index)
void *luaL_testudata(lua_State *L, int ud, const char *tname);
#elif LUA_VERSION_NUM == 502
-// Lua 5.2 modules are not expected to set a global variable, so "name" is
-// unused.
-#define lupb_newlib(L, name, l) luaL_newlib(L, l)
-#define lupb_setfuncs(L, l) luaL_setfuncs(L, l, 0)
int luaL_typerror(lua_State *L, int narg, const char *tname);
-#define LUPB_OPENFUNC(mod) luaopen_ ## mod ## upb5_2
#else
#error Only Lua 5.1 and 5.2 are supported
#endif
+#define lupb_assert(L, predicate) \
+ if (!(predicate)) \
+ luaL_error(L, "internal error: %s, %s:%d ", #predicate, __FILE__, __LINE__);
+
+// Function for initializing the core library. This function is idempotent,
+// and should be called at least once before calling any of the functions that
+// construct core upb types.
+int luaopen_upb(lua_State *L);
+
+// Gets or creates a package table for a C module that is uniquely identified by
+// "ptr". The easiest way to supply a unique "ptr" is to pass the address of a
+// static variable private in the module's .c file.
+//
+// If this module has already been registered in this lua_State, pushes it and
+// returns true.
+//
+// Otherwise, creates a new module table for this module with the given name,
+// pushes it, and registers the given top-level functions in it. It also sets
+// it as a global variable, but only if the current version of Lua expects that
+// (ie Lua 5.1/LuaJIT).
+//
+// If "false" is returned, the caller is guaranteed that this lib has not been
+// registered in this Lua state before (regardless of any funny business the
+// user might have done to the global state), so the caller can safely perform
+// one-time initialization.
+bool lupb_openlib(lua_State *L, void *ptr, const char *name,
+ const luaL_Reg *funcs);
+
+// Custom check/push functions. Unlike the Lua equivalents, they are pinned to
+// specific types (instead of lua_Number, etc), and do not allow any implicit
+// conversion or data loss.
+int64_t lupb_checkint64(lua_State *L, int narg);
+int32_t lupb_checkint32(lua_State *L, int narg);
+uint64_t lupb_checkuint64(lua_State *L, int narg);
+uint32_t lupb_checkuint32(lua_State *L, int narg);
+double lupb_checkdouble(lua_State *L, int narg);
+float lupb_checkfloat(lua_State *L, int narg);
+bool lupb_checkbool(lua_State *L, int narg);
+const char *lupb_checkname(lua_State *L, int narg);
+
+void lupb_pushint64(lua_State *L, int64_t val);
+void lupb_pushint32(lua_State *L, int32_t val);
+void lupb_pushuint64(lua_State *L, uint64_t val);
+void lupb_pushuint32(lua_State *L, uint32_t val);
+void lupb_pushdouble(lua_State *L, double val);
+void lupb_pushfloat(lua_State *L, float val);
+void lupb_pushbool(lua_State *L, bool val);
+
+// Functions for getting/pushing wrappers to various types defined in the
+// core library.
+void *lupb_refcounted_check(lua_State *L, int narg, const char *type);
+const upb_msgdef *lupb_msg_checkdef(lua_State *L, int narg);
const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg);
const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg);
-const char *lupb_checkname(lua_State *L, int narg);
-bool lupb_def_pushwrapper(lua_State *L, const upb_def *def, const void *owner);
+const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg);
+const upb_symtab *lupb_symtab_check(lua_State *L, int narg);
+
+void lupb_refcounted_pushnewrapper(lua_State *L, const upb_refcounted *obj,
+ const char *type, const void *ref_donor);
+bool lupb_def_pushwrapper(lua_State *L, const upb_def *def,
+ const void *ref_donor);
void lupb_def_pushnewrapper(lua_State *L, const upb_def *def,
- const void *owner);
+ const void *ref_donor);
+void lupb_symtab_pushwrapper(lua_State *L, const upb_symtab *s,
+ const void *ref_donor);
+void lupb_symtab_pushnewrapper(lua_State *L, const upb_symtab *s,
+ const void *ref_donor);
+
+// For constructing a new message. narg is the Lua value for the MessageDef
+// object.
+void lupb_msg_pushnew(lua_State *L, int narg);
+
+// Builds and returns a handlers object for populating a lupb_msg described by
+// the MessageDef at "narg".
+//
+// TODO(haberman): factor this so it doesn't have to take a lua_State. We
+// should be able to generate message handlers for a upb_msgdef that can be used
+// across many Lua states, so we can shared JIT code across lua_States.
+const upb_handlers *lupb_msg_newwritehandlers(lua_State *L, int narg,
+ const void *owner);
+
+// Registers a type with the given name, methods, and metamethods.
+// If "refcount_gc" is true, adds a __gc metamethod that does an unref.
+// Refcounted types must be allocated with lupb_refcounted_push[new]wrapper.
+void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
+ const luaL_Reg *mm, bool refcount_gc);
+
+// Checks the given upb_status and throws a Lua error if it is not ok.
+void lupb_checkstatus(lua_State *L, upb_status *s);
#endif // UPB_LUA_UPB_H_
diff --git a/upb/bindings/lua/upb.lua b/upb/bindings/lua/upb.lua
new file mode 100644
index 0000000..bda9dfe
--- /dev/null
+++ b/upb/bindings/lua/upb.lua
@@ -0,0 +1,146 @@
+--
+-- upb - a minimalist implementation of protocol buffers.
+--
+-- Copyright (c) 2009 Google Inc. See LICENSE for details.
+-- Author: Josh Haberman <jhaberman@gmail.com>
+--
+-- Pure-Lua support functions that are part of the "upb" module.
+-- This file is embedded and packaged into the "upb" C module binary -- it
+-- should not be installed or used directly!
+
+return function(upb)
+ -- A convenience function for building/linking/freezing defs
+ -- while maintaining their original order.
+ --
+ -- Sample usage:
+ -- local m1, m2 = upb.build_defs{
+ -- upb.MessageDef{full_name = "M1", fields = {
+ -- upb.FieldDef{
+ -- name = "m2",
+ -- number = 1,
+ -- type = upb.TYPE_MESSAGE,
+ -- subdef_name = ".M2"
+ -- },
+ -- }
+ -- },
+ -- upb.MessageDef{full_name = "M2"}
+ -- }
+ upb.build_defs = function(defs)
+ upb.SymbolTable(defs)
+ -- Lua 5.2 puts unpack in the table library.
+ return (unpack or table.unpack)(defs)
+ end
+
+ local ipairs_iter = function(array, last_index)
+ local next_index = last_index + 1
+ if next_index > #array then
+ return nil
+ end
+ return next_index, array[next_index]
+ end
+
+ -- For iterating over the indexes and values of a upb.Array.
+ --
+ -- for i, val in upb.ipairs(array) do
+ -- -- ...
+ -- end
+ upb.ipairs = function(array)
+ return ipairs_iter, array, 0
+ end
+
+ local set_named = function(obj, init)
+ for k, v in pairs(init) do
+ local func = obj["set_" .. k]
+ if not func then
+ error("Cannot set member: " .. k)
+ end
+ func(obj, v)
+ end
+ end
+
+ -- Capture references to the functions we're wrapping.
+ local RealFieldDef = upb.FieldDef
+ local RealEnumDef = upb.EnumDef
+ local RealMessageDef = upb.MessageDef
+ local RealSymbolTable = upb.SymbolTable
+
+ -- FieldDef constructor; a wrapper around the real constructor that can
+ -- set initial properties.
+ --
+ -- User can specify initialization values like so:
+ -- upb.FieldDef{label=upb.LABEL_REQUIRED, name="my_field", number=5,
+ -- type=upb.TYPE_INT32, default_value=12, type_name="Foo"}
+ upb.FieldDef = function(init)
+ local f = RealFieldDef()
+
+ if init then
+ -- Other members are often dependent on type, so set that first.
+ if init.type then
+ f:set_type(init.type)
+ init.type = nil
+ end
+
+ set_named(f, init)
+ end
+
+ return f
+ end
+
+
+ -- MessageDef constructor; a wrapper around the real constructor that can
+ -- set initial properties.
+ --
+ -- User can specify initialization values like so:
+ -- upb.MessageDef{full_name="MyMessage", extstart=8000, fields={...}}
+ upb.MessageDef = function(init)
+ local m = RealMessageDef()
+
+ if init then
+ for _, f in pairs(init.fields or {}) do
+ m:add(f)
+ end
+ init.fields = nil
+
+ set_named(m, init)
+ end
+
+ return m
+ end
+
+ -- EnumDef constructor; a wrapper around the real constructor that can
+ -- set initial properties.
+ --
+ -- User can specify initialization values like so:
+ -- upb.EnumDef{full_name="MyEnum",
+ -- values={
+ -- {"FOO_VALUE_1", 1},
+ -- {"FOO_VALUE_2", 2}
+ -- }
+ -- }
+ upb.EnumDef = function(init)
+ local e = RealEnumDef()
+
+ if init then
+ for _, val in pairs(init.values or {}) do
+ e:add(val[1], val[2])
+ end
+ init.values = nil
+
+ set_named(e, init)
+ end
+
+ return e
+ end
+
+ -- SymbolTable constructor; a wrapper around the real constructor that can
+ -- add an initial set of defs.
+ upb.SymbolTable = function(defs)
+ local s = RealSymbolTable()
+
+ if defs then
+ s:add(defs)
+ end
+
+ return s
+ end
+end
diff --git a/upb/bindings/lua/upb.pb.c b/upb/bindings/lua/upb.pb.c
new file mode 100644
index 0000000..c9f1f47
--- /dev/null
+++ b/upb/bindings/lua/upb.pb.c
@@ -0,0 +1,106 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2014 Google Inc. See LICENSE for details.
+ * Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * A Lua extension for upb.pb.
+ *
+ * Exposes all the types defined in upb/pb/{*}.h
+ * Also defines a few convenience functions on top.
+ */
+
+#include "upb/bindings/lua/upb.h"
+#include "upb/pb/decoder.h"
+
+#define LUPB_PBDECODERMETHOD "lupb.pb.decodermethod"
+
+#define MSGDEF_INDEX 1
+
+static upb_pbdecodermethod *lupb_pbdecodermethod_check(lua_State *L, int narg) {
+ return lupb_refcounted_check(L, narg, LUPB_PBDECODERMETHOD);
+}
+
+static int lupb_pbdecodermethod_new(lua_State *L) {
+ const upb_handlers *handlers = lupb_msg_newwritehandlers(L, 1, &handlers);
+
+ upb_pbdecodermethodopts opts;
+ upb_pbdecodermethodopts_init(&opts, handlers);
+
+ const upb_pbdecodermethod *m = upb_pbdecodermethod_new(&opts, &m);
+ upb_handlers_unref(handlers, &handlers);
+ lupb_refcounted_pushnewrapper(L, UPB_UPCAST(m), LUPB_PBDECODERMETHOD, &m);
+
+ // We need to keep a pointer to the MessageDef (in Lua space) so we can
+ // construct new messages in parse().
+ lua_newtable(L);
+ lua_pushvalue(L, 1);
+ lua_rawseti(L, -2, MSGDEF_INDEX);
+ lua_setuservalue(L, -2);
+
+ return 1; // The DecoderMethod wrapper.
+}
+
+// Unlike most of our exposed Lua functions, this does not correspond to an
+// actual method on the underlying DecoderMethod. But it's convenient, and
+// important to implement in C because we can do stack allocation and
+// initialization of our runtime structures like the Decoder and Sink.
+static int lupb_pbdecodermethod_parse(lua_State *L) {
+ size_t len;
+ const upb_pbdecodermethod *method = lupb_pbdecodermethod_check(L, 1);
+ const char *pb = lua_tolstring(L, 2, &len);
+
+ const upb_handlers *handlers = upb_pbdecodermethod_desthandlers(method);
+
+ lua_getuservalue(L, 1);
+ lua_rawgeti(L, -1, MSGDEF_INDEX);
+ lupb_assert(L, !lua_isnil(L, -1));
+ lupb_msg_pushnew(L, -1); // Push new message.
+ void *msg = lua_touserdata(L, -1);
+
+ // Handlers need this.
+ lua_getuservalue(L, -1);
+
+ upb_pbdecoder decoder;
+ upb_status status = UPB_STATUS_INIT;
+ upb_pbdecoder_init(&decoder, method, &status);
+ upb_sink sink;
+ upb_sink_reset(&sink, handlers, msg);
+ upb_pbdecoder_resetoutput(&decoder, &sink);
+ upb_bufsrc_putbuf(pb, len, upb_pbdecoder_input(&decoder));
+ // TODO: Our need to call uninit isn't longjmp-safe; what if the decode
+ // triggers a Lua error? uninit is only needed if the decoder
+ // dynamically-allocated a growing stack -- ditch this feature and live with
+ // the compile-time limit? Or have a custom allocation function that
+ // allocates Lua GC-rooted memory?
+ upb_pbdecoder_uninit(&decoder);
+ lupb_checkstatus(L, &status);
+
+ lua_pop(L, 1); // Uservalue.
+
+ return 1;
+}
+
+static const struct luaL_Reg lupb_pbdecodermethod_m[] = {
+ {"parse", lupb_pbdecodermethod_parse},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg toplevel_m[] = {
+ {"DecoderMethod", lupb_pbdecodermethod_new},
+ {NULL, NULL}
+};
+
+int luaopen_upb_pb(lua_State *L) {
+ luaopen_upb(L);
+
+ static char module_key;
+ if (lupb_openlib(L, &module_key, "upb.pb", toplevel_m)) {
+ return 1;
+ }
+
+ lupb_register_type(L, LUPB_PBDECODERMETHOD, lupb_pbdecodermethod_m, NULL,
+ true);
+
+ return 1;
+}
diff --git a/upb/bindings/lua/upb/descriptor.c b/upb/bindings/lua/upb/descriptor.c
new file mode 100644
index 0000000..9915e11
--- /dev/null
+++ b/upb/bindings/lua/upb/descriptor.c
@@ -0,0 +1,20 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2009 Google Inc. See LICENSE for details.
+ * Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * A Lua extension for upb/descriptor.
+ */
+
+#include "upb/bindings/lua/upb.h"
+
+static const struct luaL_Reg toplevel_m[] = {
+ {NULL, NULL}
+};
+
+int luaopen_upb_descriptor(lua_State *L) {
+ lupb_newlib(L, "upb.descriptor", toplevel_m);
+
+ return 1; // Return package table.
+}
diff --git a/upb/bindings/stdc++/string.h b/upb/bindings/stdc++/string.h
index 668f3e3..5137486 100644
--- a/upb/bindings/stdc++/string.h
+++ b/upb/bindings/stdc++/string.h
@@ -6,6 +6,8 @@
#ifndef UPB_STDCPP_H_
#define UPB_STDCPP_H_
+#include "upb/sink.h"
+
namespace upb {
template <class T>
diff --git a/upb/def.c b/upb/def.c
index 14715c8..e136ced 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -141,41 +141,86 @@ static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
upb_status_seterrmsg(s, "fielddef must have name and number set");
return false;
}
+
if (!f->type_is_set_) {
upb_status_seterrmsg(s, "fielddef type was not initialized");
return false;
}
+
if (upb_fielddef_lazy(f) &&
upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) {
upb_status_seterrmsg(s,
"only length-delimited submessage fields may be lazy");
return false;
}
+
if (upb_fielddef_hassubdef(f)) {
if (f->subdef_is_symbolic) {
- upb_status_seterrf(s,
- "field '%s' has not been resolved", upb_fielddef_name(f));
+ upb_status_seterrf(s, "field '%s.%s' has not been resolved",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
return false;
}
const upb_def *subdef = upb_fielddef_subdef(f);
if (subdef == NULL) {
+ upb_status_seterrf(s, "field %s.%s is missing required subdef",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
+ return false;
+ }
+
+ if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
upb_status_seterrf(s,
- "field %s.%s is missing required subdef",
- msgdef_name(f->msg.def), upb_fielddef_name(f));
+ "subdef of field %s.%s is not frozen or being frozen",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
return false;
- } else if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
+ }
+ }
+
+ if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ bool has_default_name = upb_fielddef_enumhasdefaultstr(f);
+ bool has_default_number = upb_fielddef_enumhasdefaultint32(f);
+
+ // Previously verified by upb_validate_enumdef().
+ assert(upb_enumdef_numvals(upb_fielddef_enumsubdef(f)) > 0);
+
+ // We've already validated that we have an associated enumdef and that it
+ // has at least one member, so at least one of these should be true.
+ // Because if the user didn't set anything, we'll pick up the enum's
+ // default, but if the user *did* set something we should at least pick up
+ // the one they set (int32 or string).
+ assert(has_default_name || has_default_number);
+
+ if (!has_default_name) {
upb_status_seterrf(s,
- "subdef of field %s.%s is not frozen or being frozen",
- msgdef_name(f->msg.def), upb_fielddef_name(f));
+ "enum default for field %s.%s (%d) is not in the enum",
+ msgdef_name(f->msg.def), upb_fielddef_name(f),
+ upb_fielddef_defaultint32(f));
return false;
- } else if (upb_fielddef_default_is_symbolic(f)) {
+ }
+
+ if (!has_default_number) {
upb_status_seterrf(s,
- "enum field %s.%s has not been resolved",
- msgdef_name(f->msg.def), upb_fielddef_name(f));
+ "enum default for field %s.%s (%s) is not in the enum",
+ msgdef_name(f->msg.def), upb_fielddef_name(f),
+ upb_fielddef_defaultstr(f, NULL));
return false;
}
+
+ // Lift the effective numeric default into the field's default slot, in case
+ // we were only getting it "by reference" from the enumdef.
+ upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f));
}
+
+ return true;
+}
+
+static bool upb_validate_enumdef(const upb_enumdef *e, upb_status *s) {
+ if (upb_enumdef_numvals(e) == 0) {
+ upb_status_seterrf(s, "enum %s has no members (must have at least one)",
+ upb_enumdef_fullname(e));
+ return false;
+ }
+
return true;
}
@@ -231,10 +276,12 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
m->selector_count = selector;
free(fields);
- return false;
+ return true;
}
bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
+ upb_status_clear(s);
+
// First perform validation, in two passes so we can check that we have a
// transitive closure without needing to search.
for (int i = 0; i < n; i++) {
@@ -246,6 +293,10 @@ bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
} else if (def->type == UPB_DEF_FIELD) {
upb_status_seterrmsg(s, "standalone fielddefs can not be frozen");
goto err;
+ } else if (def->type == UPB_DEF_ENUM) {
+ if (!upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
+ goto err;
+ }
} else {
// Set now to detect transitive closure in the second pass.
def->came_from_user = true;
@@ -259,7 +310,9 @@ bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
upb_enumdef *e = upb_dyncast_enumdef_mutable(defs[i]);
if (m) {
upb_inttable_compact(&m->itof);
- assign_msg_indices(m, s);
+ if (!assign_msg_indices(m, s)) {
+ goto err;
+ }
} else if (e) {
upb_inttable_compact(&e->iton);
}
@@ -269,13 +322,16 @@ bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
int maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
// Validation all passed; freeze the defs.
- return upb_refcounted_freeze((upb_refcounted * const *)defs, n, s, maxdepth);
+ bool ret =
+ upb_refcounted_freeze((upb_refcounted * const *)defs, n, s, maxdepth);
+ assert(!(s && ret != upb_ok(s)));
+ return ret;
err:
for (int i = 0; i < n; i++) {
defs[i]->came_from_user = false;
}
- assert(!upb_ok(s));
+ assert(!(s && upb_ok(s)));
return false;
}
@@ -348,6 +404,11 @@ void upb_enumdef_checkref(const upb_enumdef *e, const void *owner) {
upb_def_checkref(UPB_UPCAST(e), owner);
}
+bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status) {
+ upb_def *d = UPB_UPCAST(e);
+ return upb_def_freeze(&d, 1, status);
+}
+
const char *upb_enumdef_fullname(const upb_enumdef *e) {
return upb_def_fullname(UPB_UPCAST(e));
}
@@ -376,14 +437,26 @@ bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
upb_strtable_remove(&e->ntoi, name, NULL);
return false;
}
+ if (upb_enumdef_numvals(e) == 1) {
+ bool ok = upb_enumdef_setdefault(e, num, NULL);
+ UPB_ASSERT_VAR(ok, ok);
+ }
return true;
}
-int32_t upb_enumdef_default(const upb_enumdef *e) { return e->defaultval; }
+int32_t upb_enumdef_default(const upb_enumdef *e) {
+ assert(upb_enumdef_iton(e, e->defaultval));
+ return e->defaultval;
+}
-void upb_enumdef_setdefault(upb_enumdef *e, int32_t val) {
+bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) {
assert(!upb_enumdef_isfrozen(e));
+ if (!upb_enumdef_iton(e, val)) {
+ upb_status_seterrf(s, "number '%d' is not in the enum.", val);
+ return false;
+ }
e->defaultval = val;
+ return true;
}
int upb_enumdef_numvals(const upb_enumdef *e) {
@@ -427,7 +500,7 @@ int32_t upb_enum_iter_number(upb_enum_iter *iter) {
static void upb_fielddef_init_default(upb_fielddef *f);
static void upb_fielddef_uninit_default(upb_fielddef *f) {
- if (f->type_is_set_ && f->default_is_string)
+ if (f->type_is_set_ && f->default_is_string && f->defaultval.bytes)
freestr(f->defaultval.bytes);
}
@@ -451,6 +524,57 @@ static void freefield(upb_refcounted *r) {
free(f);
}
+static const char *enumdefaultstr(const upb_fielddef *f) {
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ const upb_enumdef *e = upb_fielddef_enumsubdef(f);
+ if (f->default_is_string && f->defaultval.bytes) {
+ // Default was explicitly set as a string.
+ str_t *s = f->defaultval.bytes;
+ return s->str;
+ } else if (e) {
+ if (!f->default_is_string) {
+ // Default was explicitly set as an integer; look it up in enumdef.
+ const char *name = upb_enumdef_iton(e, f->defaultval.sint);
+ if (name) {
+ return name;
+ }
+ } else {
+ // Default is completely unset; pull enumdef default.
+ if (upb_enumdef_numvals(e) > 0) {
+ const char *name = upb_enumdef_iton(e, upb_enumdef_default(e));
+ assert(name);
+ return name;
+ }
+ }
+ }
+ return NULL;
+}
+
+static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) {
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ const upb_enumdef *e = upb_fielddef_enumsubdef(f);
+ if (!f->default_is_string) {
+ // Default was explicitly set as an integer.
+ *val = f->defaultval.sint;
+ return true;
+ } else if (e) {
+ if (f->defaultval.bytes) {
+ // Default was explicitly set as a str; try to lookup corresponding int.
+ str_t *s = f->defaultval.bytes;
+ if (upb_enumdef_ntoi(e, s->str, val)) {
+ return true;
+ }
+ } else {
+ // Default is unset; try to pull in enumdef default.
+ if (upb_enumdef_numvals(e) > 0) {
+ *val = upb_enumdef_default(e);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
upb_fielddef *upb_fielddef_new(const void *owner) {
static const struct upb_refcounted_vtbl vtbl = {visitfield, freefield};
upb_fielddef *f = malloc(sizeof(*f));
@@ -490,10 +614,11 @@ upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
upb_fielddef_setlabel(newf, upb_fielddef_label(f));
upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL);
upb_fielddef_setname(newf, upb_fielddef_name(f), NULL);
- if (f->default_is_string) {
+ if (f->default_is_string && f->defaultval.bytes) {
str_t *s = f->defaultval.bytes;
upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL);
} else {
+ newf->default_is_string = f->default_is_string;
newf->defaultval = f->defaultval;
}
@@ -627,8 +752,15 @@ int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
}
int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
- chkdefaulttype(f, UPB_TYPE_INT32);
- return f->defaultval.sint;
+ if (f->type_is_set_ && upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ int32_t val;
+ bool ok = enumdefaultint32(f, &val);
+ UPB_ASSERT_VAR(ok, ok);
+ return val;
+ } else {
+ chkdefaulttype(f, UPB_TYPE_INT32);
+ return f->defaultval.sint;
+ }
}
uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
@@ -661,11 +793,21 @@ const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
assert(upb_fielddef_type(f) == UPB_TYPE_STRING ||
upb_fielddef_type(f) == UPB_TYPE_BYTES ||
upb_fielddef_type(f) == UPB_TYPE_ENUM);
+
+ if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ const char *ret = enumdefaultstr(f);
+ assert(ret);
+ // Enum defaults can't have embedded NULLs.
+ if (len) *len = strlen(ret);
+ return ret;
+ }
+
if (f->default_is_string) {
str_t *str = f->defaultval.bytes;
if (len) *len = str->len;
return str->str;
}
+
return NULL;
}
@@ -675,8 +817,7 @@ static void upb_fielddef_init_default(upb_fielddef *f) {
case UPB_TYPE_DOUBLE: f->defaultval.dbl = 0; break;
case UPB_TYPE_FLOAT: f->defaultval.flt = 0; break;
case UPB_TYPE_INT32:
- case UPB_TYPE_INT64:
- case UPB_TYPE_ENUM: f->defaultval.sint = 0; break;
+ case UPB_TYPE_INT64: f->defaultval.sint = 0; break;
case UPB_TYPE_UINT64:
case UPB_TYPE_UINT32:
case UPB_TYPE_BOOL: f->defaultval.uint = 0; break;
@@ -686,6 +827,11 @@ static void upb_fielddef_init_default(upb_fielddef *f) {
f->default_is_string = true;
break;
case UPB_TYPE_MESSAGE: break;
+ case UPB_TYPE_ENUM:
+ // This is our special sentinel that indicates "not set" for an enum.
+ f->default_is_string = true;
+ f->defaultval.bytes = NULL;
+ break;
}
}
@@ -708,8 +854,13 @@ upb_def *upb_fielddef_subdef_mutable(upb_fielddef *f) {
}
const char *upb_fielddef_subdefname(const upb_fielddef *f) {
- assert(!upb_fielddef_isfrozen(f));
- return f->subdef_is_symbolic ? f->sub.name : NULL;
+ if (f->subdef_is_symbolic) {
+ return f->sub.name;
+ } else if (f->sub.def) {
+ return upb_def_fullname(f->sub.def);
+ } else {
+ return NULL;
+ }
}
bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
@@ -871,8 +1022,8 @@ static bool checksetdefault(upb_fielddef *f, upb_fieldtype_t type) {
}
if (f->default_is_string) {
str_t *s = f->defaultval.bytes;
- assert(s);
- freestr(s);
+ assert(s || type == UPB_TYPE_ENUM);
+ if (s) freestr(s);
}
f->default_is_string = false;
return true;
@@ -924,8 +1075,8 @@ bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
if (f->default_is_string) {
str_t *s = f->defaultval.bytes;
- assert(s);
- freestr(s);
+ assert(s || f->type_ == UPB_TYPE_ENUM);
+ if (s) freestr(s);
} else {
assert(f->type_ == UPB_TYPE_ENUM);
}
@@ -942,33 +1093,15 @@ void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
upb_fielddef_setdefaultstr(f, str, str ? strlen(str) : 0, s);
}
-bool upb_fielddef_default_is_symbolic(const upb_fielddef *f) {
- return f->type_is_set_ &&
- f->default_is_string &&
- f->type_ == UPB_TYPE_ENUM;
+bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f) {
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ int32_t val;
+ return enumdefaultint32(f, &val);
}
-bool upb_fielddef_resolveenumdefault(upb_fielddef *f, upb_status *s) {
- if (!upb_fielddef_default_is_symbolic(f)) return true;
-
- str_t *str = f->defaultval.bytes;
- const upb_enumdef *e = upb_downcast_enumdef(upb_fielddef_subdef(f));
- assert(str); // Points to either a real default or the empty string.
- assert(e);
- if (str->len == 0) {
- // The "default default" for an enum is the first defined value.
- f->defaultval.sint = e->defaultval;
- } else {
- int32_t val = 0;
- if (!upb_enumdef_ntoi(e, str->str, &val)) {
- upb_status_seterrf(s, "enum default not found in enum (%s)", str->str);
- return false;
- }
- f->defaultval.sint = val;
- }
- f->default_is_string = false;
- freestr(str);
- return true;
+bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f) {
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ return enumdefaultstr(f) != NULL;
}
static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
@@ -1139,6 +1272,11 @@ void upb_msgdef_checkref(const upb_msgdef *m, const void *owner) {
upb_def_checkref(UPB_UPCAST(m), owner);
}
+bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) {
+ upb_def *d = UPB_UPCAST(m);
+ return upb_def_freeze(&d, 1, status);
+}
+
const char *upb_msgdef_fullname(const upb_msgdef *m) {
return upb_def_fullname(UPB_UPCAST(m));
}
@@ -1148,8 +1286,8 @@ bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
return upb_def_setfullname(UPB_UPCAST(m), fullname, s);
}
-bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
- const void *ref_donor, upb_status *s) {
+bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
+ upb_status *s) {
// TODO: extensions need to have a separate namespace, because proto2 allows a
// top-level extension (ie. one not in any package) to have the same name as a
// field from the message.
@@ -1162,41 +1300,29 @@ bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
// it is an extension.
// Check constraints for all fields before performing any action.
- for (int i = 0; i < n; i++) {
- upb_fielddef *f = fields[i];
- // TODO(haberman): handle the case where two fields of the input duplicate
- // name or number.
- if (upb_fielddef_containingtype(f) != NULL) {
- upb_status_seterrmsg(s, "fielddef already belongs to a message");
- return false;
- } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
- upb_status_seterrmsg(s, "field name or number were not set");
- return false;
- } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
- upb_msgdef_ntof(m, upb_fielddef_name(f))) {
- upb_status_seterrmsg(s, "duplicate field name or number");
- return false;
- }
+ if (upb_fielddef_containingtype(f) != NULL) {
+ upb_status_seterrmsg(s, "fielddef already belongs to a message");
+ return false;
+ } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
+ upb_status_seterrmsg(s, "field name or number were not set");
+ return false;
+ } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
+ upb_msgdef_ntof(m, upb_fielddef_name(f))) {
+ upb_status_seterrmsg(s, "duplicate field name or number");
+ return false;
}
// Constraint checks ok, perform the action.
- for (int i = 0; i < n; i++) {
- upb_fielddef *f = fields[i];
- release_containingtype(f);
- f->msg.def = m;
- f->msg_is_symbolic = false;
- upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
- upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
- upb_ref2(f, m);
- upb_ref2(m, f);
- if (ref_donor) upb_fielddef_unref(f, ref_donor);
- }
- return true;
-}
+ release_containingtype(f);
+ f->msg.def = m;
+ f->msg_is_symbolic = false;
+ upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
+ upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
+ upb_ref2(f, m);
+ upb_ref2(m, f);
+ if (ref_donor) upb_fielddef_unref(f, ref_donor);
-bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
- upb_status *s) {
- return upb_msgdef_addfields(m, &f, 1, ref_donor, s);
+ return true;
}
const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
@@ -1234,3 +1360,7 @@ bool upb_msg_done(const upb_msg_iter *iter) { return upb_inttable_done(iter); }
upb_fielddef *upb_msg_iter_field(const upb_msg_iter *iter) {
return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
}
+
+void upb_msg_iter_setdone(upb_msg_iter *iter) {
+ upb_inttable_iter_setdone(iter);
+}
diff --git a/upb/def.h b/upb/def.h
index a7240bf..9eb2ffc 100644
--- a/upb/def.h
+++ b/upb/def.h
@@ -264,8 +264,6 @@ class upb::FieldDef /* : public upb::Def */ {
// Functionality from upb::Def.
const char* full_name() const;
- bool set_full_name(const char* fullname, upb::Status* s);
- bool set_full_name(const std::string& fullname, upb::Status* s);
bool type_is_set() const; // Whether set_[descriptor_]type() has been called.
Type type() const; // Requires that type_is_set() == true.
@@ -278,15 +276,10 @@ class upb::FieldDef /* : public upb::Def */ {
// indicates whether this field should have lazy parsing handlers that yield
// the unparsed string for the submessage.
//
- // When we freeze, we ensure that this can only be true for length-delimited
- // message fields. Prior to freezing this can be true or false with no
- // restrictions.
- //
// TODO(haberman): I think we want to move this into a FieldOptions container
// when we add support for custom options (the FieldOptions struct will
// contain both regular FieldOptions like "lazy" *and* custom options).
bool lazy() const;
- void set_lazy(bool lazy);
// An integer that can be used as an index into an array of fields for
// whatever message this field belongs to. Guaranteed to be less than
@@ -305,11 +298,6 @@ class upb::FieldDef /* : public upb::Def */ {
const MessageDef* containing_type() const;
const char* containing_type_name();
- // This may only be called if containing_type() == NULL (ie. the field has not
- // been added to a message yet).
- bool set_containing_type_name(const char *name, Status* status);
- bool set_containing_type_name(const std::string& name, Status* status);
-
// The field's type according to the enum in descriptor.proto. This is not
// the same as UPB_TYPE_*, because it distinguishes between (for example)
// INT32 and SINT32, whereas our "type" enum does not. This return of
@@ -318,26 +306,6 @@ class upb::FieldDef /* : public upb::Def */ {
// appropriately.
DescriptorType descriptor_type() const;
- // "type" or "descriptor_type" MUST be set explicitly before the fielddef is
- // finalized. These setters require that the enum value is valid; if the
- // value did not come directly from an enum constant, the caller should
- // validate it first with the functions above (CheckFieldType(), etc).
- void set_type(Type type);
- void set_label(Label label);
- void set_descriptor_type(DescriptorType type);
- void set_is_extension(bool is_extension);
-
- // "number" and "name" must be set before the FieldDef is added to a
- // MessageDef, and may not be set after that.
- //
- // "name" is the same as full_name()/set_full_name(), but since fielddefs
- // most often use simple, non-qualified names, we provide this accessor
- // also. Generally only extensions will want to think of this name as
- // fully-qualified.
- bool set_number(uint32_t number, upb::Status* s);
- bool set_name(const char* name, upb::Status* s);
- bool set_name(const std::string& name, upb::Status* s);
-
// Convenient field type tests.
bool IsSubMessage() const;
bool IsString() const;
@@ -347,12 +315,10 @@ class upb::FieldDef /* : public upb::Def */ {
// How integers are encoded. Only meaningful for integer types.
// Defaults to UPB_INTFMT_VARIABLE, and is reset when "type" changes.
IntegerFormat integer_format() const;
- void set_integer_format(IntegerFormat format);
// Whether a submessage field is tag-delimited or not (if false, then
// length-delimited). May only be set when type() == UPB_TYPE_MESSAGE.
bool is_tag_delimited() const;
- bool set_tag_delimited(bool tag_delimited, upb::Status* s);
// Returns the non-string default value for this fielddef, which may either
// be something the client set explicitly or the "default default" (0 for
@@ -368,11 +334,87 @@ class upb::FieldDef /* : public upb::Def */ {
float default_float() const;
double default_double() const;
- // Returns the default for UPB_TYPE_STRING, UPB_TYPE_BYTES, and UPB_TYPE_ENUM
- // fields that haven't yet been resolved, The resulting string is always
- // NULL-terminated. If non-NULL, the length will be stored in *len.
+ // The resulting string is always NULL-terminated. If non-NULL, the length
+ // will be stored in *len.
const char *default_string(size_t* len) const;
+ // For frozen UPB_TYPE_ENUM fields, enum defaults can always be read as either
+ // string or int32, and both of these methods will always return true.
+ //
+ // For mutable UPB_TYPE_ENUM fields, the story is a bit more complicated.
+ // Enum defaults are unusual. They can be specified either as string or int32,
+ // but to be valid the enum must have that value as a member. And if no
+ // default is specified, the "default default" comes from the EnumDef.
+ //
+ // We allow reading the default as either an int32 or a string, but only if
+ // we have a meaningful value to report. We have a meaningful value if it was
+ // set explicitly, or if we could get the "default default" from the EnumDef.
+ // Also if you explicitly set the name and we find the number in the EnumDef
+ bool EnumHasStringDefault() const;
+ bool EnumHasInt32Default() const;
+
+ // Submessage and enum fields must reference a "subdef", which is the
+ // upb::MessageDef or upb::EnumDef that defines their type. Note that when
+ // the FieldDef is mutable it may not have a subdef *yet*, but this function
+ // still returns true to indicate that the field's type requires a subdef.
+ bool HasSubDef() const;
+
+ // Returns the enum or submessage def for this field, if any. The field's
+ // type must match (ie. you may only call enum_subdef() for fields where
+ // type() == UPB_TYPE_ENUM). Returns NULL if the subdef has not been set or
+ // is currently set symbolically.
+ const EnumDef* enum_subdef() const;
+ const MessageDef* message_subdef() const;
+
+ // Returns the generic subdef for this field. Requires that HasSubDef() (ie.
+ // only works for UPB_TYPE_ENUM and UPB_TYPE_MESSAGE fields).
+ const Def* subdef() const;
+
+ // Returns the symbolic name of the subdef. If the subdef is currently set
+ // unresolved (ie. set symbolically) returns the symbolic name. If it has
+ // been resolved to a specific subdef, returns the name from that subdef.
+ const char* subdef_name() const;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Setters (non-const methods), only valid for mutable FieldDefs!
+ //////////////////////////////////////////////////////////////////////////////
+
+ bool set_full_name(const char* fullname, upb::Status* s);
+ bool set_full_name(const std::string& fullname, upb::Status* s);
+
+ // This may only be called if containing_type() == NULL (ie. the field has not
+ // been added to a message yet).
+ bool set_containing_type_name(const char *name, Status* status);
+ bool set_containing_type_name(const std::string& name, Status* status);
+
+ // When we freeze, we ensure that this can only be true for length-delimited
+ // message fields. Prior to freezing this can be true or false with no
+ // restrictions.
+ void set_lazy(bool lazy);
+
+ // "type" or "descriptor_type" MUST be set explicitly before the fielddef is
+ // finalized. These setters require that the enum value is valid; if the
+ // value did not come directly from an enum constant, the caller should
+ // validate it first with the functions above (CheckFieldType(), etc).
+ void set_type(Type type);
+ void set_label(Label label);
+ void set_descriptor_type(DescriptorType type);
+ void set_is_extension(bool is_extension);
+
+ // "number" and "name" must be set before the FieldDef is added to a
+ // MessageDef, and may not be set after that.
+ //
+ // "name" is the same as full_name()/set_full_name(), but since fielddefs
+ // most often use simple, non-qualified names, we provide this accessor
+ // also. Generally only extensions will want to think of this name as
+ // fully-qualified.
+ bool set_number(uint32_t number, upb::Status* s);
+ bool set_name(const char* name, upb::Status* s);
+ bool set_name(const std::string& name, upb::Status* s);
+
+ void set_integer_format(IntegerFormat format);
+ bool set_tag_delimited(bool tag_delimited, upb::Status* s);
+
// Sets default value for the field. The call must exactly match the type
// of the field. Enum fields may use either setint32 or setstring to set
// the default numerically or symbolically, respectively, but symbolic
@@ -390,38 +432,6 @@ class upb::FieldDef /* : public upb::Def */ {
bool set_default_string(const std::string &str, Status *s);
void set_default_cstr(const char *str, Status *s);
- // The results of this function are only meaningful for mutable enum fields,
- // which can have a default specified either as an integer or as a string.
- // If this returns true, the default should be retrieved as default_int32(),
- // otherwise it should be retrieved with default_string().
- bool IsDefaultSymbolic() const;
-
- // If this is an enum field with a symbolic default, resolves the default and
- // returns true if resolution was successful or if this field didn't need to
- // be resolved (because it is not an enum with a symbolic default).
- bool ResolveEnumDefault(Status* s);
-
- // Submessage and enum fields must reference a "subdef", which is the
- // upb_msgdef or upb_enumdef that defines their type. Note that when the
- // fielddef is mutable it may not have a subdef *yet*, but this function
- // still returns true to indicate that the field's type requires a subdef.
- bool HasSubDef() const;
-
- // Returns the enum or submessage def or symbolic name for this field, if
- // any. Requires that upb_hassubdef(f). Returns NULL if the subdef has not
- // been set or if you ask for a subdef when the subdef is currently set
- // symbolically (or vice-versa). To access the subdef's name for a linked
- // fielddef, use upb_def_fullname(upb_fielddef_subdef(f)).
- //
- // Caller does *not* own a ref on the returned def or string.
- // upb_fielddef_subdefename() is non-const because frozen defs will never
- // have a symbolic reference (they must be resolved before the msgdef can be
- // frozen).
- const Def* subdef() const;
- const EnumDef* enum_subdef() const;
- const MessageDef* message_subdef() const;
- const char* subdef_name() const;
-
// Before a fielddef is frozen, its subdef may be set either directly (with a
// upb::Def*) or symbolically. Symbolic refs must be resolved before the
// containing msgdef can be frozen (see upb_resolve() above). upb always
@@ -530,7 +540,8 @@ bool upb_fielddef_defaultbool(const upb_fielddef *f);
float upb_fielddef_defaultfloat(const upb_fielddef *f);
double upb_fielddef_defaultdouble(const upb_fielddef *f);
const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len);
-bool upb_fielddef_default_is_symbolic(const upb_fielddef *f);
+bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f);
+bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f);
bool upb_fielddef_hassubdef(const upb_fielddef *f);
const upb_def *upb_fielddef_subdef(const upb_fielddef *f);
const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f);
@@ -559,7 +570,6 @@ bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
upb_status *s);
void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
upb_status *s);
-bool upb_fielddef_resolveenumdefault(upb_fielddef *f, upb_status *s);
bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef,
upb_status *s);
bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef,
@@ -607,6 +617,7 @@ class upb::MessageDef /* : public upb::Def */ {
// Call to freeze this MessageDef.
// WARNING: this will fail if this message has any unfrozen submessages!
+ // Messages with cycles must be frozen as a batch using upb::Def::Freeze().
bool Freeze(Status* s);
// The number of fields that belong to the MessageDef.
@@ -639,9 +650,8 @@ class upb::MessageDef /* : public upb::Def */ {
// Iteration over fields. The order is undefined.
class iterator : public std::iterator<std::forward_iterator_tag, FieldDef*> {
public:
- iterator();
- iterator(const iterator& other);
explicit iterator(MessageDef* md);
+ static iterator end(MessageDef* md);
void operator++();
FieldDef* operator*() const;
@@ -655,9 +665,8 @@ class upb::MessageDef /* : public upb::Def */ {
class const_iterator
: public std::iterator<std::forward_iterator_tag, const FieldDef*> {
public:
- const_iterator();
- const_iterator(const const_iterator& other);
explicit const_iterator(const MessageDef* md);
+ static const_iterator end(const MessageDef* md);
void operator++();
const FieldDef* operator*() const;
@@ -710,14 +719,13 @@ void upb_msgdef_unref(const upb_msgdef *m, const void *owner);
void upb_msgdef_donateref(const upb_msgdef *m, const void *from,
const void *to);
void upb_msgdef_checkref(const upb_msgdef *m, const void *owner);
+bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status);
// From upb_def.
const char *upb_msgdef_fullname(const upb_msgdef *m);
bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s);
upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner);
-bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *f, int n,
- const void *ref_donor, upb_status *s);
bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
upb_status *s);
const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i);
@@ -739,7 +747,7 @@ void upb_msg_begin(upb_msg_iter *iter, const upb_msgdef *m);
void upb_msg_next(upb_msg_iter *iter);
bool upb_msg_done(const upb_msg_iter *iter);
upb_fielddef *upb_msg_iter_field(const upb_msg_iter *iter);
-void upb_msg_iter_copy(upb_msg_iter *to, const upb_msg_iter *from);
+void upb_msg_iter_setdone(upb_msg_iter *iter);
#ifdef __cplusplus
} // extern "C
#endif
@@ -774,8 +782,14 @@ class upb::EnumDef /* : public upb::Def */ {
bool Freeze(Status* s);
// The value that is used as the default when no field default is specified.
+ // If not set explicitly, the first value that was added will be used.
+ // The default value must be a member of the enum.
+ // Requires that value_count() > 0.
int32_t default_value() const;
- void set_default_value(int32_t val);
+
+ // Sets the default value. If this value is not valid, returns false and an
+ // error message in status.
+ bool set_default_value(int32_t val, Status* status);
// Returns the number of values currently defined in the enum. Note that
// multiple names can refer to the same number, so this may be greater than
@@ -801,6 +815,8 @@ class upb::EnumDef /* : public upb::Def */ {
// Iteration over name/value pairs. The order is undefined.
// Adding an enum val invalidates any iterators.
+ //
+ // TODO: make compatible with range-for, with elements as pairs?
class Iterator {
public:
explicit Iterator(const EnumDef*);
@@ -843,6 +859,7 @@ void upb_enumdef_ref(const upb_enumdef *e, const void *owner);
void upb_enumdef_donateref(const upb_enumdef *m, const void *from,
const void *to);
void upb_enumdef_checkref(const upb_enumdef *e, const void *owner);
+bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status);
// From upb_def.
const char *upb_enumdef_fullname(const upb_enumdef *e);
@@ -850,7 +867,7 @@ bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
upb_status *s);
int32_t upb_enumdef_default(const upb_enumdef *e);
-void upb_enumdef_setdefault(upb_enumdef *e, int32_t val);
+bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s);
int upb_enumdef_numvals(const upb_enumdef *e);
bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
upb_status *status);
@@ -1188,12 +1205,6 @@ inline bool FieldDef::set_default_string(const std::string& str, Status* s) {
inline void FieldDef::set_default_cstr(const char* str, Status* s) {
return upb_fielddef_setdefaultcstr(this, str, s);
}
-inline bool FieldDef::IsDefaultSymbolic() const {
- return upb_fielddef_default_is_symbolic(this);
-}
-inline bool FieldDef::ResolveEnumDefault(Status* s) {
- return upb_fielddef_resolveenumdefault(this, s);
-}
inline bool FieldDef::HasSubDef() const { return upb_fielddef_hassubdef(this); }
inline const Def* FieldDef::subdef() const { return upb_fielddef_subdef(this); }
inline const MessageDef *FieldDef::message_subdef() const {
@@ -1248,8 +1259,7 @@ inline bool MessageDef::set_full_name(const std::string& fullname, Status* s) {
return upb_msgdef_setfullname(this, upb_safecstr(fullname), s);
}
inline bool MessageDef::Freeze(Status* status) {
- upb::Def* e = upb::upcast(this);
- return upb_def_freeze(&e, 1, status);
+ return upb_msgdef_freeze(this, status);
}
inline int MessageDef::field_count() const {
return upb_msgdef_numfields(this);
@@ -1276,20 +1286,22 @@ inline MessageDef* MessageDef::Dup(const void *owner) const {
return upb_msgdef_dup(this, owner);
}
inline MessageDef::iterator MessageDef::begin() { return iterator(this); }
-inline MessageDef::iterator MessageDef::end() { return iterator(); }
+inline MessageDef::iterator MessageDef::end() { return iterator::end(this); }
inline MessageDef::const_iterator MessageDef::begin() const {
return const_iterator(this);
}
inline MessageDef::const_iterator MessageDef::end() const {
- return const_iterator();
+ return const_iterator::end(this);
}
-inline MessageDef::iterator::iterator() {
- upb_inttable_iter_setdone(&iter_);
-}
inline MessageDef::iterator::iterator(MessageDef* md) {
upb_msg_begin(&iter_, md);
}
+inline MessageDef::iterator MessageDef::iterator::end(MessageDef* md) {
+ MessageDef::iterator iter(md);
+ upb_msg_iter_setdone(&iter.iter_);
+ return iter;
+}
inline FieldDef* MessageDef::iterator::operator*() const {
return upb_msg_iter_field(&iter_);
}
@@ -1301,12 +1313,15 @@ inline bool MessageDef::iterator::operator!=(const iterator &other) const {
return !(*this == other);
}
-inline MessageDef::const_iterator::const_iterator() {
- upb_inttable_iter_setdone(&iter_);
-}
inline MessageDef::const_iterator::const_iterator(const MessageDef* md) {
upb_msg_begin(&iter_, md);
}
+inline MessageDef::const_iterator MessageDef::const_iterator::end(
+ const MessageDef *md) {
+ MessageDef::const_iterator iter(md);
+ upb_msg_iter_setdone(&iter.iter_);
+ return iter;
+}
inline const FieldDef* MessageDef::const_iterator::operator*() const {
return upb_msg_iter_field(&iter_);
}
@@ -1349,14 +1364,13 @@ inline bool EnumDef::set_full_name(const std::string& fullname, Status* s) {
return upb_enumdef_setfullname(this, upb_safecstr(fullname), s);
}
inline bool EnumDef::Freeze(Status* status) {
- upb::Def* e = upb::upcast(this);
- return upb_def_freeze(&e, 1, status);
+ return upb_enumdef_freeze(this, status);
}
inline int32_t EnumDef::default_value() const {
return upb_enumdef_default(this);
}
-inline void EnumDef::set_default_value(int32_t val) {
- upb_enumdef_setdefault(this, val);
+inline bool EnumDef::set_default_value(int32_t val, Status* status) {
+ return upb_enumdef_setdefault(this, val, status);
}
inline int EnumDef::value_count() const { return upb_enumdef_numvals(this); }
inline bool EnumDef::AddValue(const char* name, int32_t num, Status* status) {
diff --git a/upb/descriptor/descriptor.upb.c b/upb/descriptor/descriptor.upb.c
index fa2f447..31503b1 100755
--- a/upb/descriptor/descriptor.upb.c
+++ b/upb/descriptor/descriptor.upb.c
@@ -3,294 +3,295 @@
// regenerated.
#include "upb/def.h"
+#include "upb/symtab.h"
-const upb_msgdef google_protobuf_msgs[20];
-const upb_fielddef google_protobuf_fields[81];
-const upb_enumdef google_protobuf_enums[4];
-const upb_tabent google_protobuf_strentries[204];
-const upb_tabent google_protobuf_intentries[14];
-const _upb_value google_protobuf_arrays[232];
+static const upb_msgdef msgs[20];
+static const upb_fielddef fields[81];
+static const upb_enumdef enums[4];
+static const upb_tabent strentries[236];
+static const upb_tabent intentries[14];
+static const _upb_value arrays[232];
#ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[210];
+static upb_inttable reftables[212];
#endif
-const upb_msgdef google_protobuf_msgs[20] = {
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 27, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[0], 8, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[0]),&reftables[0], &reftables[1]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[8], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[16]),&reftables[2], &reftables[3]),
- UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[11], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[20]),&reftables[4], &reftables[5]),
- UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[0], &google_protobuf_arrays[15], 8, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[24]),&reftables[6], &reftables[7]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[23], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[28]),&reftables[8], &reftables[9]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[2], &google_protobuf_arrays[27], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[32]),&reftables[10], &reftables[11]),
- UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[31], 9, 8), UPB_STRTABLE_INIT(8, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[36]),&reftables[12], &reftables[13]),
- UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 14, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[4], &google_protobuf_arrays[40], 32, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[52]),&reftables[14], &reftables[15]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 39, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[72], 12, 11), UPB_STRTABLE_INIT(11, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[68]),&reftables[16], &reftables[17]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[84], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[84]),&reftables[18], &reftables[19]),
- UPB_MSGDEF_INIT("google.protobuf.FileOptions", 21, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[6], &google_protobuf_arrays[86], 64, 9), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[88]),&reftables[20], &reftables[21]),
- UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[8], &google_protobuf_arrays[150], 16, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[104]),&reftables[22], &reftables[23]),
- UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 13, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[166], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &google_protobuf_strentries[108]),&reftables[24], &reftables[25]),
- UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[10], &google_protobuf_arrays[171], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[116]),&reftables[26], &reftables[27]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[175], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[120]),&reftables[28], &reftables[29]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &google_protobuf_intentries[12], &google_protobuf_arrays[179], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[124]),&reftables[30], &reftables[31]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[183], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[128]),&reftables[32], &reftables[33]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 14, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[185], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &google_protobuf_strentries[132]),&reftables[34], &reftables[35]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[190], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &google_protobuf_strentries[140]),&reftables[36], &reftables[37]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &google_protobuf_arrays[199], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &google_protobuf_strentries[156]),&reftables[38], &reftables[39]),
+static const upb_msgdef msgs[20] = {
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 27, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 8, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[0]),&reftables[0], &reftables[1]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[8], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]),&reftables[2], &reftables[3]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[20]),&reftables[4], &reftables[5]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[15], 8, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[24]),&reftables[6], &reftables[7]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[23], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]),&reftables[8], &reftables[9]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[27], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[32]),&reftables[10], &reftables[11]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 9, 8), UPB_STRTABLE_INIT(8, 15, UPB_CTYPE_PTR, 4, &strentries[36]),&reftables[12], &reftables[13]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 14, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[40], 32, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[52]),&reftables[14], &reftables[15]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 39, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[72], 12, 11), UPB_STRTABLE_INIT(11, 15, UPB_CTYPE_PTR, 4, &strentries[68]),&reftables[16], &reftables[17]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[84], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[84]),&reftables[18], &reftables[19]),
+ UPB_MSGDEF_INIT("google.protobuf.FileOptions", 21, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[86], 64, 9), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[88]),&reftables[20], &reftables[21]),
+ UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[150], 16, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[104]),&reftables[22], &reftables[23]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 13, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[166], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[108]),&reftables[24], &reftables[25]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[10], &arrays[171], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[116]),&reftables[26], &reftables[27]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[175], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[120]),&reftables[28], &reftables[29]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[12], &arrays[179], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[124]),&reftables[30], &reftables[31]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[183], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[128]),&reftables[32], &reftables[33]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 14, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[185], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[132]),&reftables[34], &reftables[35]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[190], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[140]),&reftables[36], &reftables[37]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[199], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[156]),&reftables[38], &reftables[39]),
};
-const upb_fielddef google_protobuf_fields[81] = {
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "aggregate_value", 8, &google_protobuf_msgs[18], NULL, 15, 6, {0},&reftables[40], &reftables[41]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "allow_alias", 2, &google_protobuf_msgs[3], NULL, 6, 1, {0},&reftables[42], &reftables[43]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "cc_generic_services", 16, &google_protobuf_msgs[10], NULL, 17, 6, {0},&reftables[44], &reftables[45]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "ctype", 1, &google_protobuf_msgs[7], UPB_UPCAST(&google_protobuf_enums[2]), 6, 1, {0},&reftables[46], &reftables[47]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "default_value", 7, &google_protobuf_msgs[6], NULL, 16, 7, {0},&reftables[48], &reftables[49]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, "dependency", 3, &google_protobuf_msgs[8], NULL, 30, 8, {0},&reftables[50], &reftables[51]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "deprecated", 3, &google_protobuf_msgs[7], NULL, 8, 3, {0},&reftables[52], &reftables[53]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, "double_value", 6, &google_protobuf_msgs[18], NULL, 11, 4, {0},&reftables[54], &reftables[55]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "end", 2, &google_protobuf_msgs[1], NULL, 3, 1, {0},&reftables[56], &reftables[57]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "enum_type", 5, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[2]), 13, 1, {0},&reftables[58], &reftables[59]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "enum_type", 4, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[2]), 16, 2, {0},&reftables[60], &reftables[61]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "experimental_map_key", 9, &google_protobuf_msgs[7], NULL, 10, 5, {0},&reftables[62], &reftables[63]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "extendee", 2, &google_protobuf_msgs[6], NULL, 7, 2, {0},&reftables[64], &reftables[65]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension", 7, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[6]), 19, 3, {0},&reftables[66], &reftables[67]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension", 6, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[6]), 22, 4, {0},&reftables[68], &reftables[69]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension_range", 5, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[1]), 19, 3, {0},&reftables[70], &reftables[71]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "field", 2, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[6]), 10, 0, {0},&reftables[72], &reftables[73]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "file", 1, &google_protobuf_msgs[9], UPB_UPCAST(&google_protobuf_msgs[8]), 5, 0, {0},&reftables[74], &reftables[75]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "go_package", 11, &google_protobuf_msgs[10], NULL, 14, 5, {0},&reftables[76], &reftables[77]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "identifier_value", 3, &google_protobuf_msgs[18], NULL, 6, 1, {0},&reftables[78], &reftables[79]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "input_type", 2, &google_protobuf_msgs[12], NULL, 7, 2, {0},&reftables[80], &reftables[81]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, "is_extension", 2, &google_protobuf_msgs[19], NULL, 5, 1, {0},&reftables[82], &reftables[83]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_generate_equals_and_hash", 20, &google_protobuf_msgs[10], NULL, 20, 9, {0},&reftables[84], &reftables[85]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_generic_services", 17, &google_protobuf_msgs[10], NULL, 18, 7, {0},&reftables[86], &reftables[87]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_multiple_files", 10, &google_protobuf_msgs[10], NULL, 13, 4, {0},&reftables[88], &reftables[89]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "java_outer_classname", 8, &google_protobuf_msgs[10], NULL, 9, 2, {0},&reftables[90], &reftables[91]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "java_package", 1, &google_protobuf_msgs[10], NULL, 6, 1, {0},&reftables[92], &reftables[93]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "label", 4, &google_protobuf_msgs[6], UPB_UPCAST(&google_protobuf_enums[0]), 11, 4, {0},&reftables[94], &reftables[95]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "lazy", 5, &google_protobuf_msgs[7], NULL, 9, 4, {0},&reftables[96], &reftables[97]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "leading_comments", 3, &google_protobuf_msgs[17], NULL, 8, 2, {0},&reftables[98], &reftables[99]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "location", 1, &google_protobuf_msgs[16], UPB_UPCAST(&google_protobuf_msgs[17]), 5, 0, {0},&reftables[100], &reftables[101]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "message_set_wire_format", 1, &google_protobuf_msgs[11], NULL, 6, 1, {0},&reftables[102], &reftables[103]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "message_type", 4, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[0]), 10, 0, {0},&reftables[104], &reftables[105]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "method", 2, &google_protobuf_msgs[14], UPB_UPCAST(&google_protobuf_msgs[12]), 6, 0, {0},&reftables[106], &reftables[107]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[6], NULL, 4, 1, {0},&reftables[108], &reftables[109]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[14], NULL, 8, 2, {0},&reftables[110], &reftables[111]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[2], NULL, 8, 2, {0},&reftables[112], &reftables[113]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[4], NULL, 4, 1, {0},&reftables[114], &reftables[115]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[8], NULL, 22, 6, {0},&reftables[116], &reftables[117]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[0], NULL, 24, 6, {0},&reftables[118], &reftables[119]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &google_protobuf_msgs[12], NULL, 4, 1, {0},&reftables[120], &reftables[121]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "name", 2, &google_protobuf_msgs[18], UPB_UPCAST(&google_protobuf_msgs[19]), 5, 0, {0},&reftables[122], &reftables[123]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, "name_part", 1, &google_protobuf_msgs[19], NULL, 2, 0, {0},&reftables[124], &reftables[125]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, "negative_int_value", 5, &google_protobuf_msgs[18], NULL, 10, 3, {0},&reftables[126], &reftables[127]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "nested_type", 3, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[0]), 13, 1, {0},&reftables[128], &reftables[129]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "no_standard_descriptor_accessor", 2, &google_protobuf_msgs[11], NULL, 7, 2, {0},&reftables[130], &reftables[131]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "number", 3, &google_protobuf_msgs[6], NULL, 10, 3, {0},&reftables[132], &reftables[133]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "number", 2, &google_protobuf_msgs[4], NULL, 7, 2, {0},&reftables[134], &reftables[135]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "optimize_for", 9, &google_protobuf_msgs[10], UPB_UPCAST(&google_protobuf_enums[3]), 12, 3, {0},&reftables[136], &reftables[137]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 4, &google_protobuf_msgs[12], UPB_UPCAST(&google_protobuf_msgs[13]), 3, 0, {0},&reftables[138], &reftables[139]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &google_protobuf_msgs[14], UPB_UPCAST(&google_protobuf_msgs[15]), 7, 1, {0},&reftables[140], &reftables[141]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &google_protobuf_msgs[2], UPB_UPCAST(&google_protobuf_msgs[3]), 7, 1, {0},&reftables[142], &reftables[143]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 8, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[10]), 20, 4, {0},&reftables[144], &reftables[145]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 8, &google_protobuf_msgs[6], UPB_UPCAST(&google_protobuf_msgs[7]), 3, 0, {0},&reftables[146], &reftables[147]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &google_protobuf_msgs[4], UPB_UPCAST(&google_protobuf_msgs[5]), 3, 0, {0},&reftables[148], &reftables[149]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 7, &google_protobuf_msgs[0], UPB_UPCAST(&google_protobuf_msgs[11]), 23, 5, {0},&reftables[150], &reftables[151]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "output_type", 3, &google_protobuf_msgs[12], NULL, 10, 3, {0},&reftables[152], &reftables[153]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "package", 2, &google_protobuf_msgs[8], NULL, 25, 7, {0},&reftables[154], &reftables[155]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "packed", 2, &google_protobuf_msgs[7], NULL, 7, 2, {0},&reftables[156], &reftables[157]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "path", 1, &google_protobuf_msgs[17], NULL, 4, 0, {0},&reftables[158], &reftables[159]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, "positive_int_value", 4, &google_protobuf_msgs[18], NULL, 9, 2, {0},&reftables[160], &reftables[161]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "public_dependency", 10, &google_protobuf_msgs[8], NULL, 35, 9, {0},&reftables[162], &reftables[163]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "py_generic_services", 18, &google_protobuf_msgs[10], NULL, 19, 8, {0},&reftables[164], &reftables[165]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "service", 6, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[14]), 16, 2, {0},&reftables[166], &reftables[167]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "source_code_info", 9, &google_protobuf_msgs[8], UPB_UPCAST(&google_protobuf_msgs[16]), 21, 5, {0},&reftables[168], &reftables[169]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "span", 2, &google_protobuf_msgs[17], NULL, 7, 1, {0},&reftables[170], &reftables[171]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "start", 1, &google_protobuf_msgs[1], NULL, 2, 0, {0},&reftables[172], &reftables[173]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, "string_value", 7, &google_protobuf_msgs[18], NULL, 12, 5, {0},&reftables[174], &reftables[175]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "trailing_comments", 4, &google_protobuf_msgs[17], NULL, 11, 3, {0},&reftables[176], &reftables[177]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "type", 5, &google_protobuf_msgs[6], UPB_UPCAST(&google_protobuf_enums[1]), 12, 5, {0},&reftables[178], &reftables[179]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "type_name", 6, &google_protobuf_msgs[6], NULL, 13, 6, {0},&reftables[180], &reftables[181]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[15], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[182], &reftables[183]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[11], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[184], &reftables[185]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[13], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[186], &reftables[187]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[7], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[188], &reftables[189]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[3], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[190], &reftables[191]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[5], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[192], &reftables[193]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &google_protobuf_msgs[10], UPB_UPCAST(&google_protobuf_msgs[18]), 5, 0, {0},&reftables[194], &reftables[195]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "value", 2, &google_protobuf_msgs[2], UPB_UPCAST(&google_protobuf_msgs[4]), 6, 0, {0},&reftables[196], &reftables[197]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "weak", 10, &google_protobuf_msgs[7], NULL, 13, 6, {0},&reftables[198], &reftables[199]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "weak_dependency", 11, &google_protobuf_msgs[8], NULL, 38, 10, {0},&reftables[200], &reftables[201]),
+static const upb_fielddef fields[81] = {
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "aggregate_value", 8, &msgs[18], NULL, 15, 6, {0},&reftables[40], &reftables[41]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "allow_alias", 2, &msgs[3], NULL, 6, 1, {0},&reftables[42], &reftables[43]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "cc_generic_services", 16, &msgs[10], NULL, 17, 6, {0},&reftables[44], &reftables[45]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "ctype", 1, &msgs[7], UPB_UPCAST(&enums[2]), 6, 1, {0},&reftables[46], &reftables[47]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "default_value", 7, &msgs[6], NULL, 16, 7, {0},&reftables[48], &reftables[49]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, "dependency", 3, &msgs[8], NULL, 30, 8, {0},&reftables[50], &reftables[51]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "deprecated", 3, &msgs[7], NULL, 8, 3, {0},&reftables[52], &reftables[53]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, "double_value", 6, &msgs[18], NULL, 11, 4, {0},&reftables[54], &reftables[55]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[56], &reftables[57]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "enum_type", 4, &msgs[0], UPB_UPCAST(&msgs[2]), 16, 2, {0},&reftables[58], &reftables[59]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "enum_type", 5, &msgs[8], UPB_UPCAST(&msgs[2]), 13, 1, {0},&reftables[60], &reftables[61]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "experimental_map_key", 9, &msgs[7], NULL, 10, 5, {0},&reftables[62], &reftables[63]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "extendee", 2, &msgs[6], NULL, 7, 2, {0},&reftables[64], &reftables[65]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension", 7, &msgs[8], UPB_UPCAST(&msgs[6]), 19, 3, {0},&reftables[66], &reftables[67]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension", 6, &msgs[0], UPB_UPCAST(&msgs[6]), 22, 4, {0},&reftables[68], &reftables[69]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "extension_range", 5, &msgs[0], UPB_UPCAST(&msgs[1]), 19, 3, {0},&reftables[70], &reftables[71]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "field", 2, &msgs[0], UPB_UPCAST(&msgs[6]), 10, 0, {0},&reftables[72], &reftables[73]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "file", 1, &msgs[9], UPB_UPCAST(&msgs[8]), 5, 0, {0},&reftables[74], &reftables[75]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "go_package", 11, &msgs[10], NULL, 14, 5, {0},&reftables[76], &reftables[77]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "identifier_value", 3, &msgs[18], NULL, 6, 1, {0},&reftables[78], &reftables[79]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "input_type", 2, &msgs[12], NULL, 7, 2, {0},&reftables[80], &reftables[81]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, "is_extension", 2, &msgs[19], NULL, 5, 1, {0},&reftables[82], &reftables[83]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_generate_equals_and_hash", 20, &msgs[10], NULL, 20, 9, {0},&reftables[84], &reftables[85]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_generic_services", 17, &msgs[10], NULL, 18, 7, {0},&reftables[86], &reftables[87]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "java_multiple_files", 10, &msgs[10], NULL, 13, 4, {0},&reftables[88], &reftables[89]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "java_outer_classname", 8, &msgs[10], NULL, 9, 2, {0},&reftables[90], &reftables[91]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "java_package", 1, &msgs[10], NULL, 6, 1, {0},&reftables[92], &reftables[93]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "label", 4, &msgs[6], UPB_UPCAST(&enums[0]), 11, 4, {0},&reftables[94], &reftables[95]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "lazy", 5, &msgs[7], NULL, 9, 4, {0},&reftables[96], &reftables[97]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "leading_comments", 3, &msgs[17], NULL, 8, 2, {0},&reftables[98], &reftables[99]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "location", 1, &msgs[16], UPB_UPCAST(&msgs[17]), 5, 0, {0},&reftables[100], &reftables[101]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "message_set_wire_format", 1, &msgs[11], NULL, 6, 1, {0},&reftables[102], &reftables[103]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "message_type", 4, &msgs[8], UPB_UPCAST(&msgs[0]), 10, 0, {0},&reftables[104], &reftables[105]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "method", 2, &msgs[14], UPB_UPCAST(&msgs[12]), 6, 0, {0},&reftables[106], &reftables[107]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[8], NULL, 22, 6, {0},&reftables[108], &reftables[109]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[14], NULL, 8, 2, {0},&reftables[110], &reftables[111]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "name", 2, &msgs[18], UPB_UPCAST(&msgs[19]), 5, 0, {0},&reftables[112], &reftables[113]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[4], NULL, 4, 1, {0},&reftables[114], &reftables[115]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[0], NULL, 24, 6, {0},&reftables[116], &reftables[117]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[12], NULL, 4, 1, {0},&reftables[118], &reftables[119]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[2], NULL, 8, 2, {0},&reftables[120], &reftables[121]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "name", 1, &msgs[6], NULL, 4, 1, {0},&reftables[122], &reftables[123]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, "name_part", 1, &msgs[19], NULL, 2, 0, {0},&reftables[124], &reftables[125]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, "negative_int_value", 5, &msgs[18], NULL, 10, 3, {0},&reftables[126], &reftables[127]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "nested_type", 3, &msgs[0], UPB_UPCAST(&msgs[0]), 13, 1, {0},&reftables[128], &reftables[129]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[11], NULL, 7, 2, {0},&reftables[130], &reftables[131]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "number", 3, &msgs[6], NULL, 10, 3, {0},&reftables[132], &reftables[133]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "number", 2, &msgs[4], NULL, 7, 2, {0},&reftables[134], &reftables[135]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "optimize_for", 9, &msgs[10], UPB_UPCAST(&enums[3]), 12, 3, {0},&reftables[136], &reftables[137]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 7, &msgs[0], UPB_UPCAST(&msgs[11]), 23, 5, {0},&reftables[138], &reftables[139]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &msgs[2], UPB_UPCAST(&msgs[3]), 7, 1, {0},&reftables[140], &reftables[141]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 8, &msgs[6], UPB_UPCAST(&msgs[7]), 3, 0, {0},&reftables[142], &reftables[143]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &msgs[4], UPB_UPCAST(&msgs[5]), 3, 0, {0},&reftables[144], &reftables[145]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 8, &msgs[8], UPB_UPCAST(&msgs[10]), 20, 4, {0},&reftables[146], &reftables[147]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 3, &msgs[14], UPB_UPCAST(&msgs[15]), 7, 1, {0},&reftables[148], &reftables[149]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "options", 4, &msgs[12], UPB_UPCAST(&msgs[13]), 3, 0, {0},&reftables[150], &reftables[151]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "output_type", 3, &msgs[12], NULL, 10, 3, {0},&reftables[152], &reftables[153]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "package", 2, &msgs[8], NULL, 25, 7, {0},&reftables[154], &reftables[155]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "packed", 2, &msgs[7], NULL, 7, 2, {0},&reftables[156], &reftables[157]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "path", 1, &msgs[17], NULL, 4, 0, {0},&reftables[158], &reftables[159]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, "positive_int_value", 4, &msgs[18], NULL, 9, 2, {0},&reftables[160], &reftables[161]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "public_dependency", 10, &msgs[8], NULL, 35, 9, {0},&reftables[162], &reftables[163]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "py_generic_services", 18, &msgs[10], NULL, 19, 8, {0},&reftables[164], &reftables[165]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "service", 6, &msgs[8], UPB_UPCAST(&msgs[14]), 16, 2, {0},&reftables[166], &reftables[167]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, "source_code_info", 9, &msgs[8], UPB_UPCAST(&msgs[16]), 21, 5, {0},&reftables[168], &reftables[169]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "span", 2, &msgs[17], NULL, 7, 1, {0},&reftables[170], &reftables[171]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[172], &reftables[173]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, "string_value", 7, &msgs[18], NULL, 12, 5, {0},&reftables[174], &reftables[175]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "trailing_comments", 4, &msgs[17], NULL, 11, 3, {0},&reftables[176], &reftables[177]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, "type", 5, &msgs[6], UPB_UPCAST(&enums[1]), 12, 5, {0},&reftables[178], &reftables[179]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, "type_name", 6, &msgs[6], NULL, 13, 6, {0},&reftables[180], &reftables[181]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[5], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[182], &reftables[183]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[15], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[184], &reftables[185]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[3], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[186], &reftables[187]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[13], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[188], &reftables[189]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[10], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[190], &reftables[191]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[11], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[192], &reftables[193]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "uninterpreted_option", 999, &msgs[7], UPB_UPCAST(&msgs[18]), 5, 0, {0},&reftables[194], &reftables[195]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, "value", 2, &msgs[2], UPB_UPCAST(&msgs[4]), 6, 0, {0},&reftables[196], &reftables[197]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, "weak", 10, &msgs[7], NULL, 13, 6, {0},&reftables[198], &reftables[199]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, "weak_dependency", 11, &msgs[8], NULL, 38, 10, {0},&reftables[200], &reftables[201]),
};
-const upb_enumdef google_protobuf_enums[4] = {
- UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &google_protobuf_strentries[160]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &google_protobuf_arrays[202], 4, 3), 0, &reftables[202], &reftables[203]),
- UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &google_protobuf_strentries[164]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &google_protobuf_arrays[206], 19, 18), 0, &reftables[204], &reftables[205]),
- UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &google_protobuf_strentries[196]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &google_protobuf_arrays[225], 3, 3), 0, &reftables[206], &reftables[207]),
- UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &google_protobuf_strentries[200]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &google_protobuf_arrays[228], 4, 3), 0, &reftables[208], &reftables[209]),
+static const upb_enumdef enums[4] = {
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[160]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[202], 4, 3), 0, &reftables[202], &reftables[203]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[164]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[206], 19, 18), 0, &reftables[204], &reftables[205]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[196]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[225], 3, 3), 0, &reftables[206], &reftables[207]),
+ UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[200]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[228], 4, 3), 0, &reftables[208], &reftables[209]),
};
-const upb_tabent google_protobuf_strentries[204] = {
- {UPB_TABKEY_STR("extension"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[14]), NULL},
+static const upb_tabent strentries[236] = {
+ {UPB_TABKEY_STR("extension"), UPB_VALUE_INIT_CONSTPTR(&fields[14]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[39]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[38]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("field"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[16]), NULL},
- {UPB_TABKEY_STR("extension_range"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[15]), NULL},
+ {UPB_TABKEY_STR("field"), UPB_VALUE_INIT_CONSTPTR(&fields[16]), NULL},
+ {UPB_TABKEY_STR("extension_range"), UPB_VALUE_INIT_CONSTPTR(&fields[15]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("nested_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[44]), NULL},
+ {UPB_TABKEY_STR("nested_type"), UPB_VALUE_INIT_CONSTPTR(&fields[44]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[55]), NULL},
- {UPB_TABKEY_STR("enum_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[10]), &google_protobuf_strentries[14]},
- {UPB_TABKEY_STR("start"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[66]), NULL},
- {UPB_TABKEY_STR("end"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[8]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[49]), NULL},
+ {UPB_TABKEY_STR("enum_type"), UPB_VALUE_INIT_CONSTPTR(&fields[9]), &strentries[14]},
+ {UPB_TABKEY_STR("start"), UPB_VALUE_INIT_CONSTPTR(&fields[66]), NULL},
+ {UPB_TABKEY_STR("end"), UPB_VALUE_INIT_CONSTPTR(&fields[8]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[78]), NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[51]), NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[36]), &google_protobuf_strentries[22]},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[75]), NULL},
+ {UPB_TABKEY_STR("value"), UPB_VALUE_INIT_CONSTPTR(&fields[78]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[50]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[40]), &strentries[22]},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[73]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("allow_alias"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[1]), NULL},
+ {UPB_TABKEY_STR("allow_alias"), UPB_VALUE_INIT_CONSTPTR(&fields[1]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("number"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[47]), NULL},
+ {UPB_TABKEY_STR("number"), UPB_VALUE_INIT_CONSTPTR(&fields[47]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[54]), NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[37]), &google_protobuf_strentries[30]},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[76]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[52]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[37]), &strentries[30]},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[71]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("label"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[27]), NULL},
+ {UPB_TABKEY_STR("label"), UPB_VALUE_INIT_CONSTPTR(&fields[27]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[34]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[41]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("number"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[46]), &google_protobuf_strentries[49]},
+ {UPB_TABKEY_STR("number"), UPB_VALUE_INIT_CONSTPTR(&fields[46]), &strentries[49]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("type_name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[70]), NULL},
- {UPB_TABKEY_STR("extendee"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[12]), NULL},
- {UPB_TABKEY_STR("type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[69]), &google_protobuf_strentries[48]},
- {UPB_TABKEY_STR("default_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[4]), NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[53]), NULL},
- {UPB_TABKEY_STR("experimental_map_key"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[11]), &google_protobuf_strentries[67]},
+ {UPB_TABKEY_STR("type_name"), UPB_VALUE_INIT_CONSTPTR(&fields[70]), NULL},
+ {UPB_TABKEY_STR("extendee"), UPB_VALUE_INIT_CONSTPTR(&fields[12]), NULL},
+ {UPB_TABKEY_STR("type"), UPB_VALUE_INIT_CONSTPTR(&fields[69]), &strentries[48]},
+ {UPB_TABKEY_STR("default_value"), UPB_VALUE_INIT_CONSTPTR(&fields[4]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[51]), NULL},
+ {UPB_TABKEY_STR("experimental_map_key"), UPB_VALUE_INIT_CONSTPTR(&fields[11]), &strentries[67]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("weak"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[79]), NULL},
+ {UPB_TABKEY_STR("weak"), UPB_VALUE_INIT_CONSTPTR(&fields[79]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("packed"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[58]), NULL},
- {UPB_TABKEY_STR("lazy"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[28]), NULL},
+ {UPB_TABKEY_STR("packed"), UPB_VALUE_INIT_CONSTPTR(&fields[58]), NULL},
+ {UPB_TABKEY_STR("lazy"), UPB_VALUE_INIT_CONSTPTR(&fields[28]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("ctype"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[3]), NULL},
+ {UPB_TABKEY_STR("ctype"), UPB_VALUE_INIT_CONSTPTR(&fields[3]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("deprecated"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[6]), NULL},
+ {UPB_TABKEY_STR("deprecated"), UPB_VALUE_INIT_CONSTPTR(&fields[6]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[74]), NULL},
- {UPB_TABKEY_STR("extension"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[13]), NULL},
- {UPB_TABKEY_STR("weak_dependency"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[80]), NULL},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[77]), NULL},
+ {UPB_TABKEY_STR("extension"), UPB_VALUE_INIT_CONSTPTR(&fields[13]), NULL},
+ {UPB_TABKEY_STR("weak_dependency"), UPB_VALUE_INIT_CONSTPTR(&fields[80]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[38]), NULL},
- {UPB_TABKEY_STR("service"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[63]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[34]), NULL},
+ {UPB_TABKEY_STR("service"), UPB_VALUE_INIT_CONSTPTR(&fields[63]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("source_code_info"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[64]), NULL},
+ {UPB_TABKEY_STR("source_code_info"), UPB_VALUE_INIT_CONSTPTR(&fields[64]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("dependency"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[5]), NULL},
- {UPB_TABKEY_STR("message_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[32]), NULL},
- {UPB_TABKEY_STR("package"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[57]), NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[52]), &google_protobuf_strentries[82]},
- {UPB_TABKEY_STR("enum_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[9]), NULL},
- {UPB_TABKEY_STR("public_dependency"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[61]), &google_protobuf_strentries[81]},
+ {UPB_TABKEY_STR("dependency"), UPB_VALUE_INIT_CONSTPTR(&fields[5]), NULL},
+ {UPB_TABKEY_STR("message_type"), UPB_VALUE_INIT_CONSTPTR(&fields[32]), NULL},
+ {UPB_TABKEY_STR("package"), UPB_VALUE_INIT_CONSTPTR(&fields[57]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[53]), &strentries[82]},
+ {UPB_TABKEY_STR("enum_type"), UPB_VALUE_INIT_CONSTPTR(&fields[10]), NULL},
+ {UPB_TABKEY_STR("public_dependency"), UPB_VALUE_INIT_CONSTPTR(&fields[61]), &strentries[81]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("file"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[17]), NULL},
+ {UPB_TABKEY_STR("file"), UPB_VALUE_INIT_CONSTPTR(&fields[17]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[77]), NULL},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[75]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("cc_generic_services"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[2]), NULL},
+ {UPB_TABKEY_STR("cc_generic_services"), UPB_VALUE_INIT_CONSTPTR(&fields[2]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("java_multiple_files"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[24]), NULL},
+ {UPB_TABKEY_STR("java_multiple_files"), UPB_VALUE_INIT_CONSTPTR(&fields[24]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("java_generic_services"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[23]), &google_protobuf_strentries[102]},
- {UPB_TABKEY_STR("java_generate_equals_and_hash"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[22]), NULL},
+ {UPB_TABKEY_STR("java_generic_services"), UPB_VALUE_INIT_CONSTPTR(&fields[23]), &strentries[102]},
+ {UPB_TABKEY_STR("java_generate_equals_and_hash"), UPB_VALUE_INIT_CONSTPTR(&fields[22]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("go_package"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[18]), NULL},
- {UPB_TABKEY_STR("java_package"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[26]), NULL},
- {UPB_TABKEY_STR("optimize_for"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[48]), NULL},
- {UPB_TABKEY_STR("py_generic_services"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[62]), NULL},
- {UPB_TABKEY_STR("java_outer_classname"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[25]), NULL},
- {UPB_TABKEY_STR("message_set_wire_format"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[31]), &google_protobuf_strentries[106]},
+ {UPB_TABKEY_STR("go_package"), UPB_VALUE_INIT_CONSTPTR(&fields[18]), NULL},
+ {UPB_TABKEY_STR("java_package"), UPB_VALUE_INIT_CONSTPTR(&fields[26]), NULL},
+ {UPB_TABKEY_STR("optimize_for"), UPB_VALUE_INIT_CONSTPTR(&fields[48]), NULL},
+ {UPB_TABKEY_STR("py_generic_services"), UPB_VALUE_INIT_CONSTPTR(&fields[62]), NULL},
+ {UPB_TABKEY_STR("java_outer_classname"), UPB_VALUE_INIT_CONSTPTR(&fields[25]), NULL},
+ {UPB_TABKEY_STR("message_set_wire_format"), UPB_VALUE_INIT_CONSTPTR(&fields[31]), &strentries[106]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[72]), NULL},
- {UPB_TABKEY_STR("no_standard_descriptor_accessor"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[45]), NULL},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[76]), NULL},
+ {UPB_TABKEY_STR("no_standard_descriptor_accessor"), UPB_VALUE_INIT_CONSTPTR(&fields[45]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[40]), NULL},
- {UPB_TABKEY_STR("input_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[20]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[39]), NULL},
+ {UPB_TABKEY_STR("input_type"), UPB_VALUE_INIT_CONSTPTR(&fields[20]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("output_type"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[56]), NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[49]), NULL},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[73]), NULL},
+ {UPB_TABKEY_STR("output_type"), UPB_VALUE_INIT_CONSTPTR(&fields[56]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[55]), NULL},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[74]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[50]), &google_protobuf_strentries[122]},
- {UPB_TABKEY_STR("method"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[33]), NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[35]), &google_protobuf_strentries[121]},
- {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[71]), NULL},
+ {UPB_TABKEY_STR("options"), UPB_VALUE_INIT_CONSTPTR(&fields[54]), &strentries[122]},
+ {UPB_TABKEY_STR("method"), UPB_VALUE_INIT_CONSTPTR(&fields[33]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[35]), &strentries[121]},
+ {UPB_TABKEY_STR("uninterpreted_option"), UPB_VALUE_INIT_CONSTPTR(&fields[72]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("location"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[30]), NULL},
+ {UPB_TABKEY_STR("location"), UPB_VALUE_INIT_CONSTPTR(&fields[30]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("span"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[65]), &google_protobuf_strentries[139]},
+ {UPB_TABKEY_STR("span"), UPB_VALUE_INIT_CONSTPTR(&fields[65]), &strentries[139]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("trailing_comments"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[68]), NULL},
- {UPB_TABKEY_STR("leading_comments"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[29]), &google_protobuf_strentries[137]},
- {UPB_TABKEY_STR("path"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[59]), NULL},
- {UPB_TABKEY_STR("double_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[7]), NULL},
+ {UPB_TABKEY_STR("trailing_comments"), UPB_VALUE_INIT_CONSTPTR(&fields[68]), NULL},
+ {UPB_TABKEY_STR("leading_comments"), UPB_VALUE_INIT_CONSTPTR(&fields[29]), &strentries[137]},
+ {UPB_TABKEY_STR("path"), UPB_VALUE_INIT_CONSTPTR(&fields[59]), NULL},
+ {UPB_TABKEY_STR("double_value"), UPB_VALUE_INIT_CONSTPTR(&fields[7]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[41]), NULL},
+ {UPB_TABKEY_STR("name"), UPB_VALUE_INIT_CONSTPTR(&fields[36]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("negative_int_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[43]), NULL},
- {UPB_TABKEY_STR("aggregate_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[0]), NULL},
+ {UPB_TABKEY_STR("negative_int_value"), UPB_VALUE_INIT_CONSTPTR(&fields[43]), NULL},
+ {UPB_TABKEY_STR("aggregate_value"), UPB_VALUE_INIT_CONSTPTR(&fields[0]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("positive_int_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[60]), NULL},
- {UPB_TABKEY_STR("identifier_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[19]), NULL},
- {UPB_TABKEY_STR("string_value"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[67]), &google_protobuf_strentries[154]},
+ {UPB_TABKEY_STR("positive_int_value"), UPB_VALUE_INIT_CONSTPTR(&fields[60]), NULL},
+ {UPB_TABKEY_STR("identifier_value"), UPB_VALUE_INIT_CONSTPTR(&fields[19]), NULL},
+ {UPB_TABKEY_STR("string_value"), UPB_VALUE_INIT_CONSTPTR(&fields[67]), &strentries[154]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("is_extension"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[21]), NULL},
- {UPB_TABKEY_STR("name_part"), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[42]), NULL},
- {UPB_TABKEY_STR("LABEL_REQUIRED"), UPB_VALUE_INIT_INT32(2), &google_protobuf_strentries[162]},
+ {UPB_TABKEY_STR("is_extension"), UPB_VALUE_INIT_CONSTPTR(&fields[21]), NULL},
+ {UPB_TABKEY_STR("name_part"), UPB_VALUE_INIT_CONSTPTR(&fields[42]), NULL},
+ {UPB_TABKEY_STR("LABEL_REQUIRED"), UPB_VALUE_INIT_INT32(2), &strentries[162]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("LABEL_REPEATED"), UPB_VALUE_INIT_INT32(3), NULL},
{UPB_TABKEY_STR("LABEL_OPTIONAL"), UPB_VALUE_INIT_INT32(1), NULL},
@@ -300,17 +301,17 @@ const upb_tabent google_protobuf_strentries[204] = {
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("TYPE_STRING"), UPB_VALUE_INIT_INT32(9), NULL},
- {UPB_TABKEY_STR("TYPE_FLOAT"), UPB_VALUE_INIT_INT32(2), &google_protobuf_strentries[193]},
+ {UPB_TABKEY_STR("TYPE_FLOAT"), UPB_VALUE_INIT_INT32(2), &strentries[193]},
{UPB_TABKEY_STR("TYPE_DOUBLE"), UPB_VALUE_INIT_INT32(1), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("TYPE_INT32"), UPB_VALUE_INIT_INT32(5), NULL},
{UPB_TABKEY_STR("TYPE_SFIXED32"), UPB_VALUE_INIT_INT32(15), NULL},
{UPB_TABKEY_STR("TYPE_FIXED32"), UPB_VALUE_INIT_INT32(7), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("TYPE_MESSAGE"), UPB_VALUE_INIT_INT32(11), &google_protobuf_strentries[194]},
+ {UPB_TABKEY_STR("TYPE_MESSAGE"), UPB_VALUE_INIT_INT32(11), &strentries[194]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("TYPE_INT64"), UPB_VALUE_INIT_INT32(3), &google_protobuf_strentries[191]},
+ {UPB_TABKEY_STR("TYPE_INT64"), UPB_VALUE_INIT_INT32(3), &strentries[191]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
@@ -318,7 +319,7 @@ const upb_tabent google_protobuf_strentries[204] = {
{UPB_TABKEY_STR("TYPE_ENUM"), UPB_VALUE_INIT_INT32(14), NULL},
{UPB_TABKEY_STR("TYPE_UINT32"), UPB_VALUE_INIT_INT32(13), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_STR("TYPE_UINT64"), UPB_VALUE_INIT_INT32(4), &google_protobuf_strentries[190]},
+ {UPB_TABKEY_STR("TYPE_UINT64"), UPB_VALUE_INIT_INT32(4), &strentries[190]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("TYPE_SFIXED64"), UPB_VALUE_INIT_INT32(16), NULL},
{UPB_TABKEY_STR("TYPE_BYTES"), UPB_VALUE_INIT_INT32(12), NULL},
@@ -328,83 +329,115 @@ const upb_tabent google_protobuf_strentries[204] = {
{UPB_TABKEY_STR("TYPE_SINT32"), UPB_VALUE_INIT_INT32(17), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("CORD"), UPB_VALUE_INIT_INT32(1), NULL},
- {UPB_TABKEY_STR("STRING"), UPB_VALUE_INIT_INT32(0), &google_protobuf_strentries[197]},
+ {UPB_TABKEY_STR("STRING"), UPB_VALUE_INIT_INT32(0), &strentries[197]},
{UPB_TABKEY_STR("STRING_PIECE"), UPB_VALUE_INIT_INT32(2), NULL},
{UPB_TABKEY_STR("CODE_SIZE"), UPB_VALUE_INIT_INT32(2), NULL},
- {UPB_TABKEY_STR("SPEED"), UPB_VALUE_INIT_INT32(1), &google_protobuf_strentries[203]},
+ {UPB_TABKEY_STR("SPEED"), UPB_VALUE_INIT_INT32(1), &strentries[203]},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
{UPB_TABKEY_STR("LITE_RUNTIME"), UPB_VALUE_INIT_INT32(3), NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_STR("google.protobuf.SourceCodeInfo.Location"), UPB_VALUE_INIT_CONSTPTR(&msgs[17]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.UninterpretedOption"), UPB_VALUE_INIT_CONSTPTR(&msgs[18]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FileDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[8]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.MethodDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[12]), NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_STR("google.protobuf.EnumValueOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[5]), NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_STR("google.protobuf.DescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[0]), &strentries[228]},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_STR("google.protobuf.SourceCodeInfo"), UPB_VALUE_INIT_CONSTPTR(&msgs[16]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FieldDescriptorProto.Type"), UPB_VALUE_INIT_CONSTPTR(&enums[1]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.DescriptorProto.ExtensionRange"), UPB_VALUE_INIT_CONSTPTR(&msgs[1]), NULL},
+ {UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
+ {UPB_TABKEY_STR("google.protobuf.EnumValueDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[4]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FieldOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[7]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FileOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[10]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.EnumDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[2]), &strentries[233]},
+ {UPB_TABKEY_STR("google.protobuf.FieldDescriptorProto.Label"), UPB_VALUE_INIT_CONSTPTR(&enums[0]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.ServiceDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[14]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FieldOptions.CType"), UPB_VALUE_INIT_CONSTPTR(&enums[2]), &strentries[229]},
+ {UPB_TABKEY_STR("google.protobuf.FileDescriptorSet"), UPB_VALUE_INIT_CONSTPTR(&msgs[9]), &strentries[235]},
+ {UPB_TABKEY_STR("google.protobuf.EnumOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[3]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FieldDescriptorProto"), UPB_VALUE_INIT_CONSTPTR(&msgs[6]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.FileOptions.OptimizeMode"), UPB_VALUE_INIT_CONSTPTR(&enums[3]), &strentries[221]},
+ {UPB_TABKEY_STR("google.protobuf.ServiceOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[15]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.MessageOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[11]), NULL},
+ {UPB_TABKEY_STR("google.protobuf.MethodOptions"), UPB_VALUE_INIT_CONSTPTR(&msgs[13]), &strentries[226]},
+ {UPB_TABKEY_STR("google.protobuf.UninterpretedOption.NamePart"), UPB_VALUE_INIT_CONSTPTR(&msgs[19]), NULL},
};
-const upb_tabent google_protobuf_intentries[14] = {
+static const upb_tabent intentries[14] = {
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[75]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[73]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[76]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[71]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[74]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[77]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[77]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[75]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[72]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[76]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[73]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[74]), NULL},
{UPB_TABKEY_NONE, UPB__VALUE_INIT_NONE, NULL},
- {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[71]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_VALUE_INIT_CONSTPTR(&fields[72]), NULL},
};
-const _upb_value google_protobuf_arrays[232] = {
+static const _upb_value arrays[232] = {
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[39]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[16]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[44]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[10]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[15]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[14]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[55]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[38]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[16]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[44]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[9]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[15]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[14]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[49]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[66]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[8]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[66]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[8]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[36]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[78]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[51]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[40]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[78]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[50]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[1]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[1]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[37]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[47]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[54]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[37]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[47]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[52]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[34]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[12]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[46]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[27]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[69]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[70]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[4]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[53]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[41]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[12]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[46]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[27]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[69]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[70]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[4]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[51]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[3]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[58]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[6]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[3]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[58]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[6]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[28]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[28]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[11]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[79]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[11]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[79]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
@@ -427,40 +460,40 @@ const _upb_value google_protobuf_arrays[232] = {
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[38]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[57]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[5]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[32]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[9]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[63]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[13]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[52]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[64]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[61]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[80]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[34]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[57]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[5]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[32]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[10]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[63]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[13]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[53]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[64]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[61]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[80]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[17]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[17]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[26]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[26]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[25]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[48]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[24]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[18]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[25]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[48]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[24]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[18]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[2]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[23]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[62]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[2]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[23]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[62]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[22]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[22]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
@@ -505,8 +538,8 @@ const _upb_value google_protobuf_arrays[232] = {
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[31]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[45]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[31]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[45]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
@@ -521,41 +554,41 @@ const _upb_value google_protobuf_arrays[232] = {
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[40]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[20]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[56]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[49]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[39]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[20]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[56]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[55]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[35]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[33]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[50]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[35]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[33]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[54]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[30]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[30]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[59]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[65]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[29]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[68]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[59]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[65]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[29]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[68]),
UPB_ARRAY_EMPTYENT,
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[41]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[19]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[60]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[43]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[7]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[67]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[0]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[36]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[19]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[60]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[43]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[7]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[67]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[0]),
UPB_ARRAY_EMPTYENT,
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[42]),
- UPB_VALUE_INIT_CONSTPTR(&google_protobuf_fields[21]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[42]),
+ UPB_VALUE_INIT_CONSTPTR(&fields[21]),
UPB_ARRAY_EMPTYENT,
UPB_VALUE_INIT_CONSTPTR("LABEL_OPTIONAL"),
UPB_VALUE_INIT_CONSTPTR("LABEL_REQUIRED"),
@@ -588,8 +621,17 @@ const _upb_value google_protobuf_arrays[232] = {
UPB_VALUE_INIT_CONSTPTR("LITE_RUNTIME"),
};
+static const upb_symtab symtab = UPB_SYMTAB_INIT(UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[204]), &reftables[210], &reftables[211]);
+
+const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner) {
+ upb_symtab_ref(&symtab, owner);
+ return &symtab;
+}
+
#ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[210] = {
+static upb_inttable reftables[212] = {
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
diff --git a/upb/descriptor/descriptor.upb.h b/upb/descriptor/descriptor.upb.h
index 72256e7..14b7308 100755
--- a/upb/descriptor/descriptor.upb.h
+++ b/upb/descriptor/descriptor.upb.h
@@ -1,11 +1,18 @@
+// This file contains accessors for a set of compiled-in defs.
+// Note that unlike Google's protobuf, it does *not* define
+// generated classes or any other kind of data structure for
+// actually storing protobufs. It only contains *defs* which
+// let you reflect over a protobuf *schema*.
+//
// This file was generated by upbc (the upb compiler).
// Do not edit -- your changes will be discarded when the file is
// regenerated.
-#ifndef GOOGLE_PROTOBUF_UPB_H_
-#define GOOGLE_PROTOBUF_UPB_H_
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
+#define GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
#include "upb/def.h"
+#include "upb/symtab.h"
#ifdef __cplusplus
extern "C" {
@@ -52,338 +59,492 @@ typedef enum {
GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZEMODE_LITE_RUNTIME = 3,
} google_protobuf_FileOptions_OptimizeMode;
-// Do not refer to these forward declarations; use the constants
-// below.
-extern const upb_msgdef google_protobuf_msgs[20];
-extern const upb_fielddef google_protobuf_fields[81];
-extern const upb_enumdef google_protobuf_enums[4];
-
-// Constants for references to defs.
-// We hide these behind macros to decouple users from the
-// details of how we have statically defined them (ie. whether
-// each def has its own symbol or lives in an array of defs).
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO &google_protobuf_msgs[0]
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE &google_protobuf_msgs[1]
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO &google_protobuf_msgs[2]
-#define GOOGLE_PROTOBUF_ENUMOPTIONS &google_protobuf_msgs[3]
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO &google_protobuf_msgs[4]
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS &google_protobuf_msgs[5]
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO &google_protobuf_msgs[6]
-#define GOOGLE_PROTOBUF_FIELDOPTIONS &google_protobuf_msgs[7]
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO &google_protobuf_msgs[8]
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET &google_protobuf_msgs[9]
-#define GOOGLE_PROTOBUF_FILEOPTIONS &google_protobuf_msgs[10]
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS &google_protobuf_msgs[11]
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO &google_protobuf_msgs[12]
-#define GOOGLE_PROTOBUF_METHODOPTIONS &google_protobuf_msgs[13]
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO &google_protobuf_msgs[14]
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS &google_protobuf_msgs[15]
-#define GOOGLE_PROTOBUF_SOURCECODEINFO &google_protobuf_msgs[16]
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION &google_protobuf_msgs[17]
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION &google_protobuf_msgs[18]
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART &google_protobuf_msgs[19]
-
-// Selector definitions.
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 15
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSTR 18
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 16
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 14
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSTR 17
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 4
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STRING 19
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END_INT32 3
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_INT32 2
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSEQ 21
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSTR 24
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSUBMSG 22
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSEQ 18
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSTR 21
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSUBMSG 19
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSEQ 17
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSTR 20
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSUBMSG 5
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STRING 22
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSEQ 20
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSTR 23
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSUBMSG 6
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STRING 25
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSEQ 9
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSTR 12
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSUBMSG 10
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSEQ 8
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSTR 11
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STRING 13
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_ENDSTR 26
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STARTSTR 25
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STRING 24
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSEQ 12
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSTR 15
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSUBMSG 13
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSEQ 11
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSTR 14
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSUBMSG 3
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STRING 16
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_ENDSTR 25
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_ENDSUBMSG 23
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_STARTSTR 24
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_STARTSUBMSG 7
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_STRING 26
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_ENDSTR 10
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STARTSTR 9
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STRING 8
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_ENDSTR 9
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_STARTSTR 8
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_STRING 10
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSEQ 5
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSTR 8
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSUBMSG 6
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSEQ 4
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSTR 7
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STRING 9
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_ALLOW_ALIAS_BOOL 6
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_ENDSTR 6
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STARTSTR 5
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STRING 4
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_INT32 7
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_ENDSTR 5
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_STARTSTR 4
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_STRING 6
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_ENDSTR 18
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STARTSTR 17
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STRING 16
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_ENDSTR 9
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STARTSTR 8
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STRING 7
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_INT32 11
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_ENDSTR 6
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STARTSTR 5
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STRING 4
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_INT32 10
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_ENDSTR 5
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_STARTSTR 4
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_STRING 6
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 12
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_ENDSTR 15
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STARTSTR 14
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STRING 13
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE_INT32 6
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_BOOL 8
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_ENDSTR 12
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STARTSTR 11
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STRING 10
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_LAZY_BOOL 9
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_BOOL 7
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_WEAK_BOOL 13
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSEQ 29
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSTR 32
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSEQ 28
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSTR 31
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STRING 30
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 12
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSTR 15
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 13
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 11
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSTR 14
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 3
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STRING 16
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSEQ 18
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSTR 21
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSUBMSG 19
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSEQ 17
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSTR 20
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSUBMSG 5
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STRING 22
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSEQ 9
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSTR 12
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSUBMSG 10
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSEQ 8
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSTR 11
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STRING 13
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_ENDSTR 24
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STARTSTR 23
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STRING 22
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_ENDSTR 22
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 20
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_STARTSTR 21
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 6
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_STRING 23
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_ENDSTR 27
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STARTSTR 26
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STRING 25
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_ENDSEQ 34
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_INT32 35
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_STARTSEQ 33
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSEQ 15
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSTR 18
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSUBMSG 16
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSEQ 14
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSTR 17
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSUBMSG 4
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STRING 19
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_ENDSTR 23
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_ENDSUBMSG 21
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_STARTSTR 22
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_STARTSUBMSG 7
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_STRING 24
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_ENDSEQ 37
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_INT32 38
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_STARTSEQ 36
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSEQ 4
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSTR 7
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSEQ 3
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSTR 6
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STRING 8
-#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES_BOOL 17
-#define GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_ENDSTR 16
-#define GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STARTSTR 15
-#define GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STRING 14
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_BOOL 20
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES_BOOL 18
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES_BOOL 13
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_ENDSTR 11
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STARTSTR 10
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STRING 9
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_ENDSTR 8
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STARTSTR 7
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STRING 6
-#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_INT32 12
-#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_BOOL 19
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_BOOL 6
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_BOOL 7
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_ENDSTR 9
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STARTSTR 8
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STRING 7
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_ENDSTR 6
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STARTSTR 5
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STRING 4
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_ENDSTR 5
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_STARTSTR 4
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_STRING 6
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_ENDSTR 12
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STARTSTR 11
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STRING 10
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSEQ 5
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSTR 8
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSUBMSG 6
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSEQ 4
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSTR 7
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STRING 9
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_ENDSTR 10
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STARTSTR 9
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STRING 8
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_ENDSTR 9
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_STARTSTR 8
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_STRING 10
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSTR 7
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSTR 6
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STRING 8
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSEQ 4
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSTR 7
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_ENDSTR 10
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STARTSTR 9
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STRING 8
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_ENDSEQ 3
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_INT32 4
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_STARTSEQ 2
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_ENDSEQ 6
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_INT32 7
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_STARTSEQ 5
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSEQ 3
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSTR 6
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STRING 8
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_ENDSTR 13
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STARTSTR 12
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STRING 11
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_ENDSTR 17
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STARTSTR 16
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STRING 15
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE_DOUBLE 11
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_ENDSTR 8
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STARTSTR 7
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STRING 6
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_BOOL 5
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_ENDSTR 4
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STARTSTR 3
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STRING 2
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSEQ 4
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSTR 7
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSUBMSG 5
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSEQ 3
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSTR 6
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSUBMSG 2
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STRING 8
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE_INT64 10
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE_UINT64 9
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_ENDSTR 14
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STARTSTR 13
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STRING 12
+const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner);
+
+// MessageDefs
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ExtensionRange");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorSet");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MessageOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MessageOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo.Location");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption.NamePart");
+ assert(m);
+ return m;
+}
+
+
+// EnumDefs
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Label");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Type");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldOptions.CType");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FileOptions.OptimizeMode");
+ assert(e);
+ return e;
+}
+
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension_range(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_field(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_nested_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_allow_alias(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_default_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_extendee(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_label(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_ctype(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_deprecated(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_experimental_map_key(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_lazy(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_packed(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_weak(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_message_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_public_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_service(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_source_code_info(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_weak_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorSet_file(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorSet(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_cc_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 16); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_go_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 20); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 17); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_multiple_files(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_outer_classname(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_optimize_for(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_py_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 18); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_message_set_wire_format(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_input_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_output_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_method(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_path(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_span(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_location(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_aggregate_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_double_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_identifier_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_negative_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_positive_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_string_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 7); }
#ifdef __cplusplus
}; // extern "C"
#endif
-#endif // GOOGLE_PROTOBUF_UPB_H_
+#ifdef __cplusplus
+
+namespace upbdefs {
+namespace google {
+namespace protobuf {
+namespace descriptor {
+inline upb::reffed_ptr<const upb::SymbolTable> SymbolTable() {
+ const upb::SymbolTable* s = upbdefs_google_protobuf_descriptor(&s);
+ return upb::reffed_ptr<const upb::SymbolTable>(s, &s);
+}
+} // namespace descriptor
+} // namespace protobuf
+} // namespace google
+
+#define RETURN_REFFED(type, func) \
+ const type* obj = func(upbdefs::google::protobuf::descriptor::SymbolTable().get()); \
+ return upb::reffed_ptr<const type>(obj);
+
+namespace google {
+namespace protobuf {
+namespace DescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_enum_type) }
+inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> extension_range() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension_range) }
+inline upb::reffed_ptr<const upb::FieldDef> field() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_field) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> nested_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_nested_type) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_options) }
+} // namespace DescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace DescriptorProto {
+namespace ExtensionRange {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange) }
+inline upb::reffed_ptr<const upb::FieldDef> end() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end) }
+inline upb::reffed_ptr<const upb::FieldDef> start() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start) }
+} // namespace ExtensionRange
+} // namespace DescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace EnumDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_value) }
+} // namespace EnumDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace EnumOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> allow_alias() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_allow_alias) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_uninterpreted_option) }
+} // namespace EnumOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace EnumValueDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_number) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_options) }
+} // namespace EnumValueDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace EnumValueOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option) }
+} // namespace EnumValueOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace FieldDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> default_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_default_value) }
+inline upb::reffed_ptr<const upb::FieldDef> extendee() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_extendee) }
+inline upb::reffed_ptr<const upb::FieldDef> label() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_label) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_number) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type) }
+inline upb::reffed_ptr<const upb::FieldDef> type_name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type_name) }
+inline upb::reffed_ptr<const upb::EnumDef> Label() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Label) }
+inline upb::reffed_ptr<const upb::EnumDef> Type() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Type) }
+} // namespace FieldDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace FieldOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> ctype() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_ctype) }
+inline upb::reffed_ptr<const upb::FieldDef> deprecated() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_deprecated) }
+inline upb::reffed_ptr<const upb::FieldDef> experimental_map_key() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_experimental_map_key) }
+inline upb::reffed_ptr<const upb::FieldDef> lazy() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_lazy) }
+inline upb::reffed_ptr<const upb::FieldDef> packed() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_packed) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_uninterpreted_option) }
+inline upb::reffed_ptr<const upb::FieldDef> weak() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_weak) }
+inline upb::reffed_ptr<const upb::EnumDef> CType() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldOptions_CType) }
+} // namespace FieldOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace FileDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_dependency) }
+inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_enum_type) }
+inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> message_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_message_type) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_package) }
+inline upb::reffed_ptr<const upb::FieldDef> public_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_public_dependency) }
+inline upb::reffed_ptr<const upb::FieldDef> service() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_service) }
+inline upb::reffed_ptr<const upb::FieldDef> source_code_info() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_source_code_info) }
+inline upb::reffed_ptr<const upb::FieldDef> weak_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_weak_dependency) }
+} // namespace FileDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace FileDescriptorSet {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorSet) }
+inline upb::reffed_ptr<const upb::FieldDef> file() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorSet_file) }
+} // namespace FileDescriptorSet
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace FileOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> cc_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_cc_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> go_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_go_package) }
+inline upb::reffed_ptr<const upb::FieldDef> java_generate_equals_and_hash() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash) }
+inline upb::reffed_ptr<const upb::FieldDef> java_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> java_multiple_files() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_multiple_files) }
+inline upb::reffed_ptr<const upb::FieldDef> java_outer_classname() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_outer_classname) }
+inline upb::reffed_ptr<const upb::FieldDef> java_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_package) }
+inline upb::reffed_ptr<const upb::FieldDef> optimize_for() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_optimize_for) }
+inline upb::reffed_ptr<const upb::FieldDef> py_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_py_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_uninterpreted_option) }
+inline upb::reffed_ptr<const upb::EnumDef> OptimizeMode() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FileOptions_OptimizeMode) }
+} // namespace FileOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace MessageOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MessageOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> message_set_wire_format() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_message_set_wire_format) }
+inline upb::reffed_ptr<const upb::FieldDef> no_standard_descriptor_accessor() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_uninterpreted_option) }
+} // namespace MessageOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace MethodDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> input_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_input_type) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> output_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_output_type) }
+} // namespace MethodDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace MethodOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodOptions_uninterpreted_option) }
+} // namespace MethodOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace ServiceDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> method() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_method) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_options) }
+} // namespace ServiceDescriptorProto
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace ServiceOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceOptions_uninterpreted_option) }
+} // namespace ServiceOptions
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace SourceCodeInfo {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo) }
+inline upb::reffed_ptr<const upb::FieldDef> location() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_location) }
+} // namespace SourceCodeInfo
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace SourceCodeInfo {
+namespace Location {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo_Location) }
+inline upb::reffed_ptr<const upb::FieldDef> leading_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments) }
+inline upb::reffed_ptr<const upb::FieldDef> path() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_path) }
+inline upb::reffed_ptr<const upb::FieldDef> span() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_span) }
+inline upb::reffed_ptr<const upb::FieldDef> trailing_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments) }
+} // namespace Location
+} // namespace SourceCodeInfo
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace UninterpretedOption {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption) }
+inline upb::reffed_ptr<const upb::FieldDef> aggregate_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_aggregate_value) }
+inline upb::reffed_ptr<const upb::FieldDef> double_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_double_value) }
+inline upb::reffed_ptr<const upb::FieldDef> identifier_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_identifier_value) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_name) }
+inline upb::reffed_ptr<const upb::FieldDef> negative_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_negative_int_value) }
+inline upb::reffed_ptr<const upb::FieldDef> positive_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_positive_int_value) }
+inline upb::reffed_ptr<const upb::FieldDef> string_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_string_value) }
+} // namespace UninterpretedOption
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace UninterpretedOption {
+namespace NamePart {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption_NamePart) }
+inline upb::reffed_ptr<const upb::FieldDef> is_extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> name_part() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part) }
+} // namespace NamePart
+} // namespace UninterpretedOption
+} // namespace protobuf
+} // namespace google
+
+} // namespace upbdefs
+
+
+#undef RETURN_REFFED
+#endif // __cplusplus
+
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
diff --git a/upb/descriptor/reader.c b/upb/descriptor/reader.c
index 9baca1d..c9425a3 100644
--- a/upb/descriptor/reader.c
+++ b/upb/descriptor/reader.c
@@ -223,11 +223,6 @@ static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) {
return false;
}
upb_enumdef *e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
- if (upb_enumdef_numvals(e) == 0) {
- // The default value of an enum (in the absence of an explicit default) is
- // its first listed value.
- upb_enumdef_setdefault(e, r->number);
- }
upb_enumdef_addval(e, r->name, r->number, status);
free(r->name);
r->name = NULL;
@@ -507,52 +502,65 @@ static bool pushextension(void *closure, const void *hd) {
return true;
}
-static const upb_fielddef *f(const upb_handlers *h, const char *name) {
- const upb_fielddef *ret = upb_msgdef_ntof(upb_handlers_msgdef(h), name);
- assert(ret);
- return ret;
-}
+#define D(name) upbdefs_google_protobuf_ ## name(s)
-static void reghandlers(void *closure, upb_handlers *h) {
- UPB_UNUSED(closure);
+static void reghandlers(const void *closure, upb_handlers *h) {
+ const upb_symtab *s = closure;
const upb_msgdef *m = upb_handlers_msgdef(h);
- if (m == GOOGLE_PROTOBUF_DESCRIPTORPROTO) {
+ if (m == D(DescriptorProto)) {
upb_handlers_setstartmsg(h, &msg_startmsg, NULL);
upb_handlers_setendmsg(h, &msg_endmsg, NULL);
- upb_handlers_setstring(h, f(h, "name"), &msg_onname, NULL);
- upb_handlers_setendsubmsg(h, f(h, "field"), &msg_onendfield, NULL);
- upb_handlers_setendsubmsg(h, f(h, "extension"), &pushextension, NULL);
- } else if (m == GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO) {
+ upb_handlers_setstring(h, D(DescriptorProto_name), &msg_onname, NULL);
+ upb_handlers_setendsubmsg(h, D(DescriptorProto_field), &msg_onendfield,
+ NULL);
+ upb_handlers_setendsubmsg(h, D(DescriptorProto_extension), &pushextension,
+ NULL);
+ } else if (m == D(FileDescriptorProto)) {
upb_handlers_setstartmsg(h, &file_startmsg, NULL);
upb_handlers_setendmsg(h, &file_endmsg, NULL);
- upb_handlers_setstring(h, f(h, "package"), &file_onpackage, NULL);
- upb_handlers_setendsubmsg(h, f(h, "extension"), &pushextension, NULL);
- } else if (m == GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO) {
+ upb_handlers_setstring(h, D(FileDescriptorProto_package), &file_onpackage,
+ NULL);
+ upb_handlers_setendsubmsg(h, D(FileDescriptorProto_extension), &pushextension,
+ NULL);
+ } else if (m == D(EnumValueDescriptorProto)) {
upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
- upb_handlers_setstring(h, f(h, "name"), &enumval_onname, NULL);
- upb_handlers_setint32(h, f(h, "number"), &enumval_onnumber, NULL);
- } else if (m == GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO) {
+ upb_handlers_setstring(h, D(EnumValueDescriptorProto_name), &enumval_onname, NULL);
+ upb_handlers_setint32(h, D(EnumValueDescriptorProto_number), &enumval_onnumber,
+ NULL);
+ } else if (m == D(EnumDescriptorProto)) {
upb_handlers_setstartmsg(h, &enum_startmsg, NULL);
upb_handlers_setendmsg(h, &enum_endmsg, NULL);
- upb_handlers_setstring(h, f(h, "name"), &enum_onname, NULL);
- } else if (m == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO) {
+ upb_handlers_setstring(h, D(EnumDescriptorProto_name), &enum_onname, NULL);
+ } else if (m == D(FieldDescriptorProto)) {
upb_handlers_setstartmsg(h, &field_startmsg, NULL);
upb_handlers_setendmsg(h, &field_endmsg, NULL);
- upb_handlers_setint32(h, f(h, "type"), &field_ontype, NULL);
- upb_handlers_setint32(h, f(h, "label"), &field_onlabel, NULL);
- upb_handlers_setint32(h, f(h, "number"), &field_onnumber, NULL);
- upb_handlers_setstring(h, f(h, "name"), &field_onname, NULL);
- upb_handlers_setstring(h, f(h, "type_name"), &field_ontypename, NULL);
- upb_handlers_setstring(h, f(h, "extendee"), &field_onextendee, NULL);
- upb_handlers_setstring(h, f(h, "default_value"), &field_ondefaultval, NULL);
- } else if (m == GOOGLE_PROTOBUF_FIELDOPTIONS) {
- upb_handlers_setbool(h, f(h, "lazy"), &field_onlazy, NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_type), &field_ontype,
+ NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_label), &field_onlabel,
+ NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_number), &field_onnumber,
+ NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_name), &field_onname,
+ NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_type_name),
+ &field_ontypename, NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_extendee),
+ &field_onextendee, NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_default_value),
+ &field_ondefaultval, NULL);
+ } else if (m == D(FieldOptions)) {
+ upb_handlers_setbool(h, D(FieldOptions_lazy), &field_onlazy, NULL);
}
}
+#undef D
+
const upb_handlers *upb_descreader_newhandlers(const void *owner) {
- return upb_handlers_newfrozen(
- GOOGLE_PROTOBUF_FILEDESCRIPTORSET, owner, reghandlers, NULL);
+ const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s);
+ const upb_handlers *h = upb_handlers_newfrozen(
+ upbdefs_google_protobuf_FileDescriptorSet(s), owner, reghandlers, s);
+ upb_symtab_unref(s, &s);
+ return h;
}
diff --git a/upb/handlers-inl.h b/upb/handlers-inl.h
index 0bee5a2..25cbf0a 100644
--- a/upb/handlers-inl.h
+++ b/upb/handlers-inl.h
@@ -164,7 +164,7 @@ template <class T> struct remove_constptr<const T *> { typedef T *type; };
template <class T, class U> struct disable_if_same { typedef void Type; };
template <class T> struct disable_if_same<T, T> {};
-template <class T> void DeletePointer(void *p) { delete static_cast<T *>(p); }
+template <class T> void DeletePointer(void *p) { delete static_cast<T>(p); }
template <class T1, class T2>
struct FirstUnlessVoid {
@@ -802,6 +802,7 @@ struct ConvertParams<BoundFunc5<R, P1, P2, P3, P4, P5, F, I> > {
const FieldDef *f, \
const Handlers::utype ## Handler& handler) { \
assert(!handler.registered_); \
+ handler.AddCleanup(this); \
handler.registered_ = true; \
return upb_handlers_set##ltype(this, f, handler.handler_, &handler.attr_); \
} \
@@ -876,8 +877,10 @@ template<class T> const void *UniquePtrForType() {
template <class T>
template <class F>
inline Handler<T>::Handler(F func)
- : registered_(false) {
- upb_handlerattr_sethandlerdata(&attr_, func.GetData(), func.GetCleanup());
+ : registered_(false),
+ cleanup_data_(func.GetData()),
+ cleanup_func_(func.GetCleanup()) {
+ upb_handlerattr_sethandlerdata(&attr_, func.GetData());
typedef typename ReturnOf<T>::Return Return;
typedef typename ConvertParams<F>::Func ConvertedParamsFunc;
typedef typename MaybeWrapReturn<ConvertedParamsFunc, Return>::Func
@@ -911,9 +914,8 @@ inline Handler<T>::~Handler() {
inline HandlerAttributes::HandlerAttributes() { upb_handlerattr_init(this); }
inline HandlerAttributes::~HandlerAttributes() { upb_handlerattr_uninit(this); }
-inline bool HandlerAttributes::SetHandlerData(void *hd,
- upb_handlerfree *cleanup) {
- return upb_handlerattr_sethandlerdata(this, hd, cleanup);
+inline bool HandlerAttributes::SetHandlerData(const void *hd) {
+ return upb_handlerattr_sethandlerdata(this, hd);
}
inline const void* HandlerAttributes::handler_data() const {
return upb_handlerattr_handlerdata(this);
@@ -965,7 +967,7 @@ inline reffed_ptr<Handlers> Handlers::New(const MessageDef *m) {
}
inline reffed_ptr<const Handlers> Handlers::NewFrozen(
const MessageDef *m, upb_handlers_callback *callback,
- void *closure) {
+ const void *closure) {
const upb_handlers *h = upb_handlers_newfrozen(m, &h, callback, closure);
return reffed_ptr<const Handlers>(h, &h);
}
@@ -1001,58 +1003,70 @@ inline bool Handlers::Freeze(const std::vector<Handlers*>& h, Status* status) {
inline const MessageDef *Handlers::message_def() const {
return upb_handlers_msgdef(this);
}
+inline bool Handlers::AddCleanup(void *p, upb_handlerfree *func) {
+ return upb_handlers_addcleanup(this, p, func);
+}
inline bool Handlers::SetStartMessageHandler(
const Handlers::StartMessageHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setstartmsg(this, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetEndMessageHandler(
const Handlers::EndMessageHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setendmsg(this, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetStartStringHandler(const FieldDef *f,
const StartStringHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setstartstr(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetEndStringHandler(const FieldDef *f,
const EndFieldHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setendstr(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetStringHandler(const FieldDef *f,
const StringHandler& handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setstring(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetStartSequenceHandler(
const FieldDef *f, const StartFieldHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setstartseq(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetStartSubMessageHandler(
const FieldDef *f, const StartFieldHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setstartsubmsg(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetEndSubMessageHandler(const FieldDef *f,
const EndFieldHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setendsubmsg(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetEndSequenceHandler(const FieldDef *f,
const EndFieldHandler &handler) {
assert(!handler.registered_);
handler.registered_ = true;
+ handler.AddCleanup(this);
return upb_handlers_setendseq(this, f, handler.handler_, &handler.attr_);
}
inline bool Handlers::SetSubHandlers(const FieldDef *f, const Handlers *sub) {
diff --git a/upb/handlers.c b/upb/handlers.c
index be035ba..024cd0c 100644
--- a/upb/handlers.c
+++ b/upb/handlers.c
@@ -21,12 +21,17 @@ char _upb_noclosure;
static void freehandlers(upb_refcounted *r) {
upb_handlers *h = (upb_handlers*)r;
- for (int i = 0; i < h->msg->selector_count; i++) {
- upb_handlerfree *cleanup = h->table[i].attr.cleanup;
- if (cleanup) {
- cleanup(h->table[i].attr.handler_data_);
- }
+
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &h->cleanup_);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ void *val = (void*)upb_inttable_iter_key(&i);
+ upb_value func_val = upb_inttable_iter_value(&i);
+ upb_handlerfree *func = upb_value_getfptr(func_val);
+ func(val);
}
+
+ upb_inttable_uninit(&h->cleanup_);
upb_msgdef_unref(h->msg, h);
free(h->sub);
free(h);
@@ -49,7 +54,7 @@ static const struct upb_refcounted_vtbl vtbl = {visithandlers, freehandlers};
typedef struct {
upb_inttable tab; // maps upb_msgdef* -> upb_handlers*.
upb_handlers_callback *callback;
- void *closure;
+ const void *closure;
} dfs_state;
// TODO(haberman): discard upb_handlers* objects that do not actually have any
@@ -283,6 +288,7 @@ upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
h->sub = calloc(md->submsg_field_count, sizeof(*h->sub));
if (!h->sub) goto oom;
if (!upb_refcounted_init(UPB_UPCAST(h), &vtbl, owner)) goto oom;
+ if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
// calloc() above initialized all handlers to NULL.
return h;
@@ -295,7 +301,7 @@ oom:
const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
const void *owner,
upb_handlers_callback *callback,
- void *closure) {
+ const void *closure) {
dfs_state state;
state.callback = callback;
state.closure = closure;
@@ -396,6 +402,15 @@ const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
+ if (upb_inttable_lookupptr(&h->cleanup_, p, NULL)) {
+ return false;
+ }
+ bool ok = upb_inttable_insertptr(&h->cleanup_, p, upb_value_fptr(func));
+ UPB_ASSERT_VAR(ok, ok);
+ return true;
+}
+
/* "Static" methods ***********************************************************/
@@ -584,10 +599,8 @@ void upb_handlerattr_uninit(upb_handlerattr *attr) {
UPB_UNUSED(attr);
}
-bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, void *hd,
- upb_handlerfree *cleanup) {
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd) {
attr->handler_data_ = hd;
- attr->cleanup = cleanup;
return true;
}
diff --git a/upb/handlers.h b/upb/handlers.h
index a03c99e..6a8193a 100644
--- a/upb/handlers.h
+++ b/upb/handlers.h
@@ -91,7 +91,6 @@ extern char _upb_noclosure;
// A selector refers to a specific field handler in the Handlers object
// (for example: the STARTSUBMSG handler for field "field15").
typedef int32_t upb_selector_t;
-typedef void upb_func();
#ifdef __cplusplus
extern "C" {
@@ -140,12 +139,9 @@ class upb::HandlerAttributes {
~HandlerAttributes();
// Sets the handler data that will be passed as the second parameter of the
- // handler.
- //
- // Warning: if you use these attributes for multiple handlers, the
- // cleanup handler will be called once for each handler it was successfully
- // set on.
- bool SetHandlerData(void *handler_data, upb_handlerfree *cleanup);
+ // handler. To free this pointer when the handlers are freed, call
+ // Handlers::AddCleanup().
+ bool SetHandlerData(const void *handler_data);
const void* handler_data() const;
// Use this to specify the type of the closure. This will be checked against
@@ -175,14 +171,13 @@ class upb::HandlerAttributes {
#else
struct upb_handlerattr {
#endif
- void *handler_data_;
- upb_handlerfree *cleanup;
+ const void *handler_data_;
const void *closure_type_;
const void *return_closure_type_;
bool alwaysok_;
};
-#define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, NULL, false}
+#define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, false}
typedef struct {
upb_func *func;
@@ -292,7 +287,7 @@ class upb::Handlers {
// correct type.
typedef void GenericFunction();
- typedef void HandlersCallback(void *closure, upb_handlers *h);
+ typedef void HandlersCallback(const void *closure, upb_handlers *h);
// Returns a new handlers object for the given frozen msgdef.
// Returns NULL if memory allocation failed.
@@ -305,7 +300,7 @@ class upb::Handlers {
// subhandlers set by the callback will be overwritten.
static reffed_ptr<const Handlers> NewFrozen(const MessageDef *m,
HandlersCallback *callback,
- void *closure);
+ const void *closure);
// Functionality from upb::RefCounted.
bool IsFrozen() const;
@@ -335,6 +330,11 @@ class upb::Handlers {
// Returns the msgdef associated with this handlers object.
const MessageDef* message_def() const;
+ // Adds the given pointer and function to the list of cleanup functions that
+ // will be run when these handlers are freed. If this pointer has previously
+ // been registered, the function returns false and does nothing.
+ bool AddCleanup(void *ptr, upb_handlerfree *cleanup);
+
// Sets the startmsg handler for the message, which is defined as follows:
//
// bool startmsg(MyType* closure) {
@@ -534,6 +534,7 @@ struct upb_handlers {
const upb_msgdef *msg;
const upb_handlers **sub;
const void *top_closure_type;
+ upb_inttable cleanup_;
upb_status status_; // Used only when mutable.
upb_handlers_tabent table[1]; // Dynamically-sized field handler array.
};
@@ -619,11 +620,20 @@ template <class T> class Handler {
~Handler();
private:
+ void AddCleanup(Handlers* h) const {
+ if (cleanup_func_) {
+ bool ok = h->AddCleanup(cleanup_data_, cleanup_func_);
+ UPB_ASSERT_VAR(ok, ok);
+ }
+ }
+
UPB_DISALLOW_COPY_AND_ASSIGN(Handler);
friend class Handlers;
FuncPtr handler_;
mutable HandlerAttributes attr_;
mutable bool registered_;
+ void *cleanup_data_;
+ upb_handlerfree *cleanup_func_;
};
} // namespace upb
@@ -657,8 +667,7 @@ size_t upb_bufhandle_objofs(const upb_bufhandle *h);
void upb_handlerattr_init(upb_handlerattr *attr);
void upb_handlerattr_uninit(upb_handlerattr *attr);
-bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, void *hd,
- upb_handlerfree *cleanup);
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd);
bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type);
const void *upb_handlerattr_closuretype(const upb_handlerattr *attr);
bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
@@ -673,13 +682,13 @@ UPB_INLINE const void *upb_handlerattr_handlerdata(
}
// upb_handlers
-typedef void upb_handlers_callback(void *closure, upb_handlers *h);
+typedef void upb_handlers_callback(const void *closure, upb_handlers *h);
upb_handlers *upb_handlers_new(const upb_msgdef *m,
const void *owner);
const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
const void *owner,
upb_handlers_callback *callback,
- void *closure);
+ const void *closure);
bool upb_handlers_isfrozen(const upb_handlers *h);
void upb_handlers_ref(const upb_handlers *h, const void *owner);
void upb_handlers_unref(const upb_handlers *h, const void *owner);
@@ -690,6 +699,7 @@ void upb_handlers_checkref(const upb_handlers *h, const void *owner);
const upb_status *upb_handlers_status(upb_handlers *h);
void upb_handlers_clearerr(upb_handlers *h);
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr);
diff --git a/upb/json/typed_printer.c b/upb/json/typed_printer.c
new file mode 100644
index 0000000..e79cfc1
--- /dev/null
+++ b/upb/json/typed_printer.c
@@ -0,0 +1,322 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2014 Google Inc. See LICENSE for details.
+ * Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * Uses YAJL at the moment; this is not exposed publicly and will likely change
+ * in the future.
+ *
+ */
+
+#include "upb/json/typed_printer.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <yajl/yajl_gen.h>
+
+static void doprint(void *_p, const char *buf, unsigned int len) {
+ upb_json_typedprinter *p = _p;
+ // YAJL doesn't support returning an error status here, so we can't properly
+ // support clients who return a value other than "len" here.
+ size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
+ UPB_ASSERT_VAR(n, n == len);
+}
+
+// StringPiece; a pointer plus a length.
+typedef struct {
+ const char *ptr;
+ size_t len;
+} strpc;
+
+strpc *newstrpc(upb_handlers *h, const upb_fielddef *f) {
+ strpc *ret = malloc(sizeof(*ret));
+ ret->ptr = upb_fielddef_name(f);
+ ret->len = strlen(ret->ptr);
+ upb_handlers_addcleanup(h, ret, free);
+ return ret;
+}
+
+#define CHKYAJL(x) if ((x) != yajl_gen_status_ok) return false;
+#define CHK(x) if (!(x)) return false;
+
+// Wrapper for yajl_gen_string that takes "const char*" instead of "const
+// unsigned char*".
+static yajl_gen_status yajl_gen_string2(yajl_gen yajl, const char *ptr,
+ size_t len) {
+ return yajl_gen_string(yajl, (const unsigned char *)ptr, len);
+}
+
+// Wrappers for yajl_gen_number() that formats floating point values
+// according to our custom formats. Right now we use %.8g and %.17g
+// for float/double, respectively, to match proto2::util::JsonFormat's
+// defaults. May want to change this later.
+
+static yajl_gen_status upbyajl_gen_double(yajl_gen yajl, double val) {
+ char data[64];
+ int n = snprintf(data, sizeof(data), "%.17g", val);
+ CHK(n > 0 && n < sizeof(data));
+ return yajl_gen_number(yajl, data, n);
+}
+
+static yajl_gen_status upbyajl_gen_float(yajl_gen yajl, float val) {
+ char data[64];
+ int n = snprintf(data, sizeof(data), "%.8g", val);
+ CHK(n > 0 && n < sizeof(data));
+ return yajl_gen_number(yajl, data, n);
+}
+
+static yajl_gen_status upbyajl_gen_uint64(yajl_gen yajl,
+ unsigned long long val) {
+ char data[64];
+ int n = snprintf(data, sizeof(data), "%llu", val);
+ CHK(n > 0 && n < sizeof(data));
+ return yajl_gen_number(yajl, data, n);
+}
+
+static bool putkey(void *closure, const void *handler_data) {
+ upb_json_typedprinter *p = closure;
+ const strpc *key = handler_data;
+ CHKYAJL(yajl_gen_string2(p->yajl_gen_, key->ptr, key->len));
+ return true;
+}
+
+#define TYPE_HANDLERS(type, yajlfunc) \
+ static bool put##type(void *closure, const void *handler_data, type val) { \
+ upb_json_typedprinter *p = closure; \
+ UPB_UNUSED(handler_data); \
+ CHKYAJL(yajlfunc(p->yajl_gen_, val)); \
+ return true; \
+ } \
+ static bool scalar_##type(void *closure, const void *handler_data, \
+ type val) { \
+ CHK(putkey(closure, handler_data)); \
+ CHK(put##type(closure, handler_data, val)); \
+ return true; \
+ }
+
+TYPE_HANDLERS(double, upbyajl_gen_double);
+TYPE_HANDLERS(float, upbyajl_gen_float);
+TYPE_HANDLERS(bool, yajl_gen_bool);
+TYPE_HANDLERS(int32_t, yajl_gen_integer);
+TYPE_HANDLERS(uint32_t, yajl_gen_integer);
+TYPE_HANDLERS(int64_t, yajl_gen_integer);
+TYPE_HANDLERS(uint64_t, upbyajl_gen_uint64);
+
+#undef TYPE_HANDLERS
+
+static void *startsubmsg(void *closure, const void *handler_data) {
+ return putkey(closure, handler_data) ? closure : UPB_BREAK;
+}
+
+static bool startmap(void *closure, const void *handler_data) {
+ UPB_UNUSED(handler_data);
+ upb_json_typedprinter *p = closure;
+ if (p->depth_++ == 0) {
+ upb_bytessink_start(p->output_, 0, &p->subc_);
+ }
+ CHKYAJL(yajl_gen_map_open(p->yajl_gen_));
+ return true;
+}
+
+static bool endmap(void *closure, const void *handler_data, upb_status *s) {
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(s);
+ upb_json_typedprinter *p = closure;
+ if (--p->depth_ == 0) {
+ upb_bytessink_end(p->output_);
+ }
+ CHKYAJL(yajl_gen_map_close(p->yajl_gen_));
+ return true;
+}
+
+static void *startseq(void *closure, const void *handler_data) {
+ upb_json_typedprinter *p = closure;
+ CHK(putkey(closure, handler_data));
+ CHKYAJL(yajl_gen_array_open(p->yajl_gen_));
+ return closure;
+}
+
+static bool endseq(void *closure, const void *handler_data) {
+ UPB_UNUSED(handler_data);
+ upb_json_typedprinter *p = closure;
+ CHKYAJL(yajl_gen_array_close(p->yajl_gen_));
+ return true;
+}
+
+static size_t putstr(void *closure, const void *handler_data, const char *str,
+ size_t len, const upb_bufhandle *handle) {
+ UPB_UNUSED(handle);
+ upb_json_typedprinter *p = closure;
+ CHKYAJL(yajl_gen_string2(p->yajl_gen_, str, len));
+ return len;
+}
+
+// This has to Base64 encode the bytes, because JSON has no "bytes" type.
+static size_t putbytes(void *closure, const void *handler_data, const char *str,
+ size_t len, const upb_bufhandle *handle) {
+ UPB_UNUSED(handle);
+ upb_json_typedprinter *p = closure;
+
+ // This is the regular base64, not the "web-safe" version.
+ static const char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ // Base64-encode.
+ char data[16000];
+ const char *limit = data + sizeof(data);
+ const unsigned char *from = (const unsigned char*)str;
+ char *to = data;
+ size_t remaining = len;
+ while (remaining > 2) {
+ // TODO(haberman): handle encoded lengths > sizeof(data)
+ UPB_ASSERT_VAR(limit, (limit - to) >= 4);
+
+ to[0] = base64[from[0] >> 2];
+ to[1] = base64[((from[0] & 0x3) << 4) + (from[1] >> 4)];
+ to[2] = base64[((from[1] & 0xf) << 2) + (from[2] >> 6)];
+ to[3] = base64[from[2] & 0x3f];
+
+ remaining -= 3;
+ to += 4;
+ from += 3;
+ }
+
+ size_t bytes = to - data;
+ if (yajl_gen_string2(p->yajl_gen_, data, bytes) != yajl_gen_status_ok) {
+ return 0;
+ }
+ return len;
+}
+
+static size_t scalar_str(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putkey(closure, handler_data));
+ CHK(putstr(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static size_t scalar_bytes(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putkey(closure, handler_data));
+ CHK(putbytes(closure, handler_data, str, len, handle));
+ return len;
+}
+
+void sethandlers(const void *closure, upb_handlers *h) {
+ UPB_UNUSED(closure);
+
+ upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlers_setstartmsg(h, startmap, &empty_attr);
+ upb_handlers_setendmsg(h, endmap, &empty_attr);
+
+#define TYPE(type, name, ctype) \
+ case type: \
+ if (upb_fielddef_isseq(f)) { \
+ upb_handlers_set##name(h, f, put##ctype, &empty_attr); \
+ } else { \
+ upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
+ } \
+ break;
+
+ upb_msg_iter i;
+ upb_msg_begin(&i, upb_handlers_msgdef(h));
+ for(; !upb_msg_done(&i); upb_msg_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+
+ upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&name_attr, newstrpc(h, f));
+
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstartseq(h, f, startseq, &name_attr);
+ upb_handlers_setendseq(h, f, endseq, &empty_attr);
+ }
+
+ switch (upb_fielddef_type(f)) {
+ TYPE(UPB_TYPE_FLOAT, float, float);
+ TYPE(UPB_TYPE_DOUBLE, double, double);
+ TYPE(UPB_TYPE_BOOL, bool, bool);
+ TYPE(UPB_TYPE_ENUM, int32, int32_t);
+ TYPE(UPB_TYPE_INT32, int32, int32_t);
+ TYPE(UPB_TYPE_UINT32, uint32, uint32_t);
+ TYPE(UPB_TYPE_INT64, int64, int64_t);
+ TYPE(UPB_TYPE_UINT64, uint64, uint64_t);
+ case UPB_TYPE_STRING:
+ // XXX: this doesn't support strings that span buffers yet.
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstring(h, f, putstr, &empty_attr);
+ } else {
+ upb_handlers_setstring(h, f, scalar_str, &name_attr);
+ }
+ break;
+ case UPB_TYPE_BYTES:
+ // XXX: this doesn't support strings that span buffers yet.
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstring(h, f, putbytes, &empty_attr);
+ } else {
+ upb_handlers_setstring(h, f, scalar_bytes, &name_attr);
+ }
+ break;
+ case UPB_TYPE_MESSAGE:
+ if (!upb_fielddef_isseq(f)) {
+ upb_handlers_setstartsubmsg(h, f, startsubmsg, &name_attr);
+ }
+ break;
+ }
+
+ upb_handlerattr_uninit(&name_attr);
+ }
+
+ upb_handlerattr_uninit(&empty_attr);
+#undef TYPE
+}
+
+// YAJL unfortunately does not support stack allocation, nor resetting an
+// allocated object, so we have to allocate on the heap and reallocate whenever
+// there is a reset.
+static void reset(upb_json_typedprinter *p, bool free) {
+ if (free) {
+ yajl_gen_free(p->yajl_gen_);
+ }
+ p->yajl_gen_ = yajl_gen_alloc(NULL);
+ yajl_gen_config(p->yajl_gen_, yajl_gen_validate_utf8, 0);
+ yajl_gen_config(p->yajl_gen_, yajl_gen_print_callback, &doprint, p);
+}
+
+/* Public API *****************************************************************/
+
+void upb_json_typedprinter_init(upb_json_typedprinter *p,
+ const upb_handlers *h) {
+ p->output_ = NULL;
+ p->depth_ = 0;
+ reset(p, false);
+ upb_sink_reset(&p->input_, h, p);
+}
+
+void upb_json_typedprinter_uninit(upb_json_typedprinter *p) {
+ yajl_gen_free(p->yajl_gen_);
+}
+
+void upb_json_typedprinter_reset(upb_json_typedprinter *p) {
+ p->depth_ = 0;
+ reset(p, true);
+}
+
+void upb_json_typedprinter_resetoutput(upb_json_typedprinter *p,
+ upb_bytessink *output) {
+ upb_json_typedprinter_reset(p);
+ p->output_ = output;
+}
+
+upb_sink *upb_json_typedprinter_input(upb_json_typedprinter *p) {
+ return &p->input_;
+}
+
+const upb_handlers *upb_json_typedprinter_newhandlers(const upb_msgdef *md,
+ const void *owner) {
+ return upb_handlers_newfrozen(md, owner, sethandlers, NULL);
+}
diff --git a/upb/json/typed_printer.h b/upb/json/typed_printer.h
new file mode 100644
index 0000000..190aeb3
--- /dev/null
+++ b/upb/json/typed_printer.h
@@ -0,0 +1,116 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2014 Google Inc. See LICENSE for details.
+ * Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * upb::json::TypedPrinter allows you to create handlers that emit JSON
+ * according to a specific protobuf schema.
+ */
+
+#ifndef UPB_JSON_TYPED_PRINTER_H_
+#define UPB_JSON_TYPED_PRINTER_H_
+
+#include "upb/sink.h"
+
+#ifdef __cplusplus
+namespace upb {
+namespace json {
+class TypedPrinter;
+} // namespace json
+} // namespace upb
+
+typedef upb::json::TypedPrinter upb_json_typedprinter;
+#else
+struct upb_json_typedprinter;
+typedef struct upb_json_typedprinter upb_json_typedprinter;
+#endif
+
+
+/* upb::json::TypedPrinter ****************************************************/
+
+#ifdef __cplusplus
+
+// Prints an incoming stream of data to a BytesSink in JSON format.
+class upb::json::TypedPrinter {
+ public:
+ TypedPrinter(const upb::Handlers* handlers);
+ ~TypedPrinter();
+
+ // Resets the state of the printer, so that it will expect to begin a new
+ // document.
+ void Reset();
+
+ // Resets the output pointer which will serve as our closure. Implies
+ // Reset().
+ void ResetOutput(BytesSink* output);
+
+ // The input to the printer.
+ Sink* input();
+
+ // Returns handlers for printing according to the specified schema.
+ static reffed_ptr<const Handlers> NewHandlers(const upb::MessageDef* md);
+
+ private:
+#else
+struct upb_json_typedprinter {
+#endif
+ upb_sink input_;
+ // Pointer to yajl_gen; void* here so we don't have to include YAJL headers.
+ void *yajl_gen_;
+ void *subc_;
+ upb_bytessink *output_;
+ // We track the depth so that we know when to emit startstr/endstr on the
+ // output.
+ int depth_;
+};
+
+// Native C API.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void upb_json_typedprinter_init(upb_json_typedprinter *p,
+ const upb_handlers *h);
+void upb_json_typedprinter_uninit(upb_json_typedprinter *p);
+void upb_json_typedprinter_reset(upb_json_typedprinter *p);
+void upb_json_typedprinter_resetoutput(upb_json_typedprinter *p,
+ upb_bytessink *output);
+upb_sink *upb_json_typedprinter_input(upb_json_typedprinter *p);
+const upb_handlers *upb_json_typedprinter_newhandlers(const upb_msgdef *md,
+ const void *owner);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#ifdef __cplusplus
+
+namespace upb {
+namespace json {
+inline TypedPrinter::TypedPrinter(const upb::Handlers* handlers) {
+ upb_json_typedprinter_init(this, handlers);
+}
+inline TypedPrinter::~TypedPrinter() {
+ upb_json_typedprinter_uninit(this);
+}
+inline void TypedPrinter::Reset() {
+ upb_json_typedprinter_reset(this);
+}
+inline void TypedPrinter::ResetOutput(BytesSink* output) {
+ upb_json_typedprinter_resetoutput(this, output);
+}
+inline Sink* TypedPrinter::input() {
+ return upb_json_typedprinter_input(this);
+}
+inline reffed_ptr<const Handlers> TypedPrinter::NewHandlers(
+ const upb::MessageDef *md) {
+ const Handlers* h = upb_json_typedprinter_newhandlers(md, &h);
+ return reffed_ptr<const Handlers>(h, &h);
+}
+} // namespace json
+} // namespace upb
+
+#endif
+
+#endif // UPB_JSON_TYPED_PRINTER_H_
diff --git a/upb/pb/compile_decoder.c b/upb/pb/compile_decoder.c
index 400d6fa..59bd03b 100644
--- a/upb/pb/compile_decoder.c
+++ b/upb/pb/compile_decoder.c
@@ -4,7 +4,14 @@
* Copyright (c) 2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
- * Code to compile a upb::MessageDef into bytecode for decoding that message.
+ * Code to compile a upb::Handlers into bytecode for decoding a protobuf
+ * according to that specific schema and destination handlers.
+ *
+ * Compiling to bytecode is always the first step. If we are using the
+ * interpreted decoder we leave it as bytecode and interpret that. If we are
+ * using a JIT decoder we use a code generator to turn the bytecode into native
+ * code, LLVM IR, etc.
+ *
* Bytecode definition is in decoder.int.h.
*/
diff --git a/upb/pb/compile_decoder_x64.dasc b/upb/pb/compile_decoder_x64.dasc
index 97fb5ce..9eec6a5 100644
--- a/upb/pb/compile_decoder_x64.dasc
+++ b/upb/pb/compile_decoder_x64.dasc
@@ -5,8 +5,7 @@
|// Author: Josh Haberman <jhaberman@gmail.com>
|//
|// JIT compiler for upb_pbdecoder on x86-64. Generates machine code from the
-|// bytecode generated in compile_decoder.c, but unlike the interpreter we bind
-|// to a specific set of handlers for greater efficiency.
+|// bytecode generated in compile_decoder.c.
|
|.arch x64
|.actionlist upb_jit_actionlist
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index 9c54b8a..1098e63 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -3,6 +3,19 @@
*
* Copyright (c) 2008-2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * This file implements a VM for the interpreted (bytecode) decoder.
+ *
+ * Bytecode must previously have been generated using the bytecode compiler in
+ * compile_decoder.c. This decoder then walks through the bytecode op-by-op to
+ * parse the input.
+ *
+ * Decoding is fully resumable; we just keep a pointer to the current bytecode
+ * instruction and resume from there. A fair amount of the logic here is to
+ * handle the fact that values can span buffer seams and we have to be able to
+ * be capable of suspending/resuming from any byte in the stream. This
+ * sometimes requires keeping a few trailing bytes from the last buffer around
+ * in the "residual" buffer.
*/
#include <inttypes.h>
@@ -55,7 +68,7 @@ static bool consumes_input(opcode op) {
}
}
-static bool in_residual_buf(upb_pbdecoder *d, const char *p);
+static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
// It's unfortunate that we have to micro-manage the compiler this way,
// especially since this tuning is necessarily specific to one hardware
@@ -83,18 +96,14 @@ void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
// How many bytes can be safely read from d->ptr without reading past end-of-buf
// or past the current delimited end.
-static size_t curbufleft(upb_pbdecoder *d) {
+static size_t curbufleft(const upb_pbdecoder *d) {
assert(d->data_end >= d->ptr);
return d->data_end - d->ptr;
}
-static const char *ptr(upb_pbdecoder *d) {
- return d->ptr;
-}
-
-// Overall offset of d->ptr.
-uint64_t offset(upb_pbdecoder *d) {
- return d->bufstart_ofs + (ptr(d) - d->buf);
+// Overall stream offset of d->ptr.
+uint64_t offset(const upb_pbdecoder *d) {
+ return d->bufstart_ofs + (d->ptr - d->buf);
}
// Advances d->ptr.
@@ -107,12 +116,12 @@ static bool in_buf(const char *p, const char *buf, const char *end) {
return p >= buf && p <= end;
}
-static bool in_residual_buf(upb_pbdecoder *d, const char *p) {
+static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
return in_buf(p, d->residual, d->residual_end);
}
-// Calculates the delim_end value, which represents a combination of the
-// current buffer and the stack, so must be called whenever either is updated.
+// Calculates the delim_end value, which is affected by both the current buffer
+// and the parsing stack, so must be called whenever either is updated.
static void set_delim_end(upb_pbdecoder *d) {
size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
if (delim_ofs <= (d->end - d->buf)) {
@@ -141,8 +150,8 @@ static void checkpoint(upb_pbdecoder *d) {
// The assertion here is in the interests of efficiency, not correctness.
// We are trying to ensure that we don't checkpoint() more often than
// necessary.
- assert(d->checkpoint != ptr(d));
- d->checkpoint = ptr(d);
+ assert(d->checkpoint != d->ptr);
+ d->checkpoint = d->ptr;
}
// Resumes the decoder from an initial state or from a previous suspend.
@@ -154,14 +163,14 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
d->handle = handle;
if (d->residual_end > d->residual) {
// We have residual bytes from the last buffer.
- assert(ptr(d) == d->residual);
+ assert(d->ptr == d->residual);
} else {
switchtobuf(d, buf, buf + size);
}
- d->checkpoint = ptr(d);
+ d->checkpoint = d->ptr;
if (d->top->groupnum < 0) {
CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0));
- d->checkpoint = ptr(d);
+ d->checkpoint = d->ptr;
}
return DECODE_OK;
}
@@ -198,7 +207,7 @@ static size_t suspend_save(upb_pbdecoder *d) {
// Checkpoint was in residual buf; append user byte(s) to residual buf.
assert((d->residual_end - d->residual) + d->size_param <=
sizeof(d->residual));
- if (!in_residual_buf(d, ptr(d))) {
+ if (!in_residual_buf(d, d->ptr)) {
d->bufstart_ofs -= (d->residual_end - d->residual);
}
memcpy(d->residual_end, d->buf_param, d->size_param);
@@ -209,7 +218,7 @@ static size_t suspend_save(upb_pbdecoder *d) {
d->ptr = d->checkpoint;
size_t save = curbufleft(d);
assert(save <= sizeof(d->residual));
- memcpy(d->residual, ptr(d), save);
+ memcpy(d->residual, d->ptr, save);
d->residual_end = d->residual + save;
d->bufstart_ofs = offset(d);
}
@@ -218,8 +227,11 @@ static size_t suspend_save(upb_pbdecoder *d) {
return d->size_param;
}
+// Skips "bytes" bytes in the stream, which may be more than available. If we
+// skip more bytes than are available, we return a long read count to the caller
+// indicating how many bytes the caller should skip before passing a new buffer.
static int32_t skip(upb_pbdecoder *d, size_t bytes) {
- assert(!in_residual_buf(d, ptr(d)) || d->size_param == 0);
+ assert(!in_residual_buf(d, d->ptr) || d->size_param == 0);
if (curbufleft(d) >= bytes) {
// Skipped data is all in current buffer.
advance(d, bytes);
@@ -235,19 +247,24 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) {
}
}
+// Copies the next "bytes" bytes into "buf" and advances the stream.
+// Requires that this many bytes are available in the current buffer.
FORCEINLINE void consumebytes(upb_pbdecoder *d, void *buf, size_t bytes) {
assert(bytes <= curbufleft(d));
- memcpy(buf, ptr(d), bytes);
+ memcpy(buf, d->ptr, bytes);
advance(d, bytes);
}
+// Slow path for getting the next "bytes" bytes, regardless of whether they are
+// available in the current buffer or not. Returns a status code as described
+// in decoder.int.h.
static NOINLINE int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
size_t bytes) {
const size_t avail = curbufleft(d);
consumebytes(d, buf, avail);
bytes -= avail;
assert(bytes > 0);
- if (in_residual_buf(d, ptr(d))) {
+ if (in_residual_buf(d, d->ptr)) {
advancetobuf(d, d->buf_param, d->size_param);
}
if (curbufleft(d) >= bytes) {
@@ -261,6 +278,8 @@ static NOINLINE int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
}
}
+// Gets the next "bytes" bytes, regardless of whether they are available in the
+// current buffer or not. Returns a status code as described in decoder.int.h.
FORCEINLINE int32_t getbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
if (curbufleft(d) >= bytes) {
// Buffer has enough data to satisfy.
@@ -274,8 +293,8 @@ FORCEINLINE int32_t getbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
static NOINLINE size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
size_t bytes) {
size_t ret = curbufleft(d);
- memcpy(buf, ptr(d), ret);
- if (in_residual_buf(d, ptr(d))) {
+ memcpy(buf, d->ptr, ret);
+ if (in_residual_buf(d, d->ptr)) {
size_t copy = UPB_MIN(bytes - ret, d->size_param);
memcpy(buf + ret, d->buf_param, copy);
ret += copy;
@@ -285,7 +304,7 @@ static NOINLINE size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
FORCEINLINE size_t peekbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
if (curbufleft(d) >= bytes) {
- memcpy(buf, ptr(d), bytes);
+ memcpy(buf, d->ptr, bytes);
return bytes;
} else {
return peekbytes_slow(d, buf, bytes);
@@ -295,6 +314,8 @@ FORCEINLINE size_t peekbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
/* Decoding of wire types *****************************************************/
+// Slow path for decoding a varint from the current buffer position.
+// Returns a status code as described in decoder.int.h.
NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
uint64_t *u64) {
*u64 = 0;
@@ -312,19 +333,21 @@ NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
return DECODE_OK;
}
+// Decodes a varint from the current buffer position.
+// Returns a status code as described in decoder.int.h.
FORCEINLINE int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
- if (curbufleft(d) > 0 && !(*ptr(d) & 0x80)) {
- *u64 = *ptr(d);
+ if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
+ *u64 = *d->ptr;
advance(d, 1);
return DECODE_OK;
} else if (curbufleft(d) >= 10) {
// Fast case.
- upb_decoderet r = upb_vdecode_fast(ptr(d));
+ upb_decoderet r = upb_vdecode_fast(d->ptr);
if (r.p == NULL) {
seterr(d, kUnterminatedVarint);
return upb_pbdecoder_suspend(d);
}
- advance(d, r.p - ptr(d));
+ advance(d, r.p - d->ptr);
*u64 = r.val;
return DECODE_OK;
} else {
@@ -333,6 +356,8 @@ FORCEINLINE int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
}
}
+// Decodes a 32-bit varint from the current buffer position.
+// Returns a status code as described in decoder.int.h.
FORCEINLINE int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
uint64_t u64;
int32_t ret = decode_varint(d, &u64);
@@ -349,16 +374,22 @@ FORCEINLINE int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
return DECODE_OK;
}
+// Decodes a fixed32 from the current buffer position.
+// Returns a status code as described in decoder.int.h.
// TODO: proper byte swapping for big-endian machines.
FORCEINLINE int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
return getbytes(d, u32, 4);
}
+// Decodes a fixed64 from the current buffer position.
+// Returns a status code as described in decoder.int.h.
// TODO: proper byte swapping for big-endian machines.
FORCEINLINE int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
return getbytes(d, u64, 8);
}
+// Non-static versions of the above functions.
+// These are called by the JIT for fallback paths.
int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) {
return decode_fixed32(d, u32);
}
@@ -370,6 +401,7 @@ int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) {
static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; }
static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; }
+// Pushes a frame onto the decoder stack.
static bool push(upb_pbdecoder *d, uint64_t end) {
upb_pbdecoder_frame *fr = d->top;
@@ -400,6 +432,7 @@ static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
return true;
}
+// Pops a frame from the decoder stack.
static void pop(upb_pbdecoder *d) { d->top--; }
NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
@@ -477,7 +510,7 @@ have_tag:
return DECODE_OK;
}
- if (ptr(d) == d->delim_end) {
+ if (d->ptr == d->delim_end) {
seterr(d, "Enclosing submessage ended in the middle of value or group");
// Unlike most errors we notice during parsing, right now we have consumed
// all of the user's input.
@@ -516,6 +549,12 @@ static void goto_endmsg(upb_pbdecoder *d) {
d->pc = d->top->base + upb_value_getuint64(v);
}
+// Parses a tag and jumps to the corresponding bytecode instruction for this
+// field.
+//
+// If the tag is unknown (or the wire type doesn't match), parses the field as
+// unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode
+// instruction for the end of message.
static int32_t dispatch(upb_pbdecoder *d) {
upb_inttable *dispatch = d->top->dispatch;
@@ -564,6 +603,8 @@ upb_pbdecoder_frame *outer_frame(upb_pbdecoder *d) {
/* The main decoding loop *****************************************************/
+// The main decoder VM function. Uses traditional bytecode dispatch loop with a
+// switch() statement.
size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
size_t size, const upb_bufhandle *handle) {
upb_pbdecoder *d = closure;
@@ -591,15 +632,15 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
opcode op = getop(instruction);
uint32_t arg = instruction >> 8;
int32_t longofs = arg;
- assert(ptr(d) != d->residual_end);
+ assert(d->ptr != d->residual_end);
#ifdef UPB_DUMP_BYTECODE
fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d "
"%x %s (%d)\n",
(int)offset(d),
- (int)(ptr(d) - d->buf),
- (int)(d->data_end - ptr(d)),
- (int)(d->end - ptr(d)),
- (int)((d->top->end_ofs - d->bufstart_ofs) - (ptr(d) - d->buf)),
+ (int)(d->ptr - d->buf),
+ (int)(d->data_end - d->ptr),
+ (int)(d->end - d->ptr),
+ (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)),
(int)(d->pc - 1 - group->bytecode),
upb_pbdecoder_getopname(op),
arg);
@@ -657,25 +698,24 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
)
VMCASE(OP_STRING,
uint32_t len = curbufleft(d);
- size_t n = upb_sink_putstring(&d->top->sink, arg, ptr(d), len, handle);
+ size_t n = upb_sink_putstring(&d->top->sink, arg, d->ptr, len, handle);
if (n > len) {
if (n > d->top->end_ofs - offset(d)) {
seterr(d, "Tried to skip past end of string.");
return upb_pbdecoder_suspend(d);
} else {
- return skip(d, n);
+ int32_t ret = skip(d, n);
+ // This shouldn't return DECODE_OK, because n > len.
+ assert(ret >= 0);
+ return ret;
}
- } else if (n < len) {
- advance(d, n);
+ }
+ advance(d, n);
+ if (n < len || d->delim_end == NULL) {
+ // We aren't finished with this string yet.
+ d->pc--; // Repeat OP_STRING.
+ if (n > 0) checkpoint(d);
return upb_pbdecoder_suspend(d);
- } else {
- advance(d, n);
- if (d->delim_end == NULL) { // String extends beyond this buf?
- d->pc--; // Do OP_STRING again when we resume.
- d->bufstart_ofs += size;
- d->residual_end = d->residual;
- return size;
- }
}
)
VMCASE(OP_ENDSTR,
@@ -703,8 +743,8 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
VMCASE(OP_CHECKDELIM,
// We are guaranteed of this assert because we never allow ourselves to
// consume bytes beyond data_end, which covers delim_end when non-NULL.
- assert(!(d->delim_end && ptr(d) > d->delim_end));
- if (ptr(d) == d->delim_end)
+ assert(!(d->delim_end && d->ptr > d->delim_end));
+ if (d->ptr == d->delim_end)
d->pc += longofs;
)
VMCASE(OP_CALL,
@@ -721,7 +761,7 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
VMCASE(OP_TAG1,
CHECK_SUSPEND(curbufleft(d) > 0);
uint8_t expected = (arg >> 8) & 0xff;
- if (*ptr(d) == expected) {
+ if (*d->ptr == expected) {
advance(d, 1);
} else {
int8_t shortofs;
@@ -740,7 +780,7 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
uint16_t expected = (arg >> 8) & 0xffff;
if (curbufleft(d) >= 2) {
uint16_t actual;
- memcpy(&actual, ptr(d), 2);
+ memcpy(&actual, d->ptr, 2);
if (expected == actual) {
advance(d, 2);
} else {
@@ -856,6 +896,10 @@ void upb_pbdecoder_reset(upb_pbdecoder *d) {
d->call_len = 1;
}
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
+ return offset(d);
+}
+
// Not currently required, but to support outgrowing the static stack we need
// this.
void upb_pbdecoder_uninit(upb_pbdecoder *d) {
diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h
index 586d2d5..0aa35ec 100644
--- a/upb/pb/decoder.h
+++ b/upb/pb/decoder.h
@@ -1,11 +1,18 @@
/*
* upb - a minimalist implementation of protocol buffers.
*
- * Copyright (c) 2009-2013 Google Inc. See LICENSE for details.
+ * Copyright (c) 2009-2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb::pb::Decoder implements a high performance, streaming, resumable decoder
* for the binary protobuf format.
+ *
+ * This interface works the same regardless of what decoder backend is being
+ * used. A client of this class does not need to know whether decoding is using
+ * a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default,
+ * it will always use the fastest available decoder. However, you can call
+ * set_allow_jit(false) to disable any JIT decoder that might be available.
+ * This is primarily useful for testing purposes.
*/
#ifndef UPB_DECODER_H_
@@ -200,6 +207,15 @@ class upb::pb::Decoder {
// Resets the state of the decoder.
void Reset();
+ // Returns number of bytes successfully parsed.
+ //
+ // This can be useful for determining the stream position where an error
+ // occurred.
+ //
+ // This value may not be up-to-date when called from inside a parsing
+ // callback.
+ uint64_t BytesParsed() const;
+
// Resets the output sink of the Decoder.
// The given sink must match method()->dest_handlers().
//
@@ -332,6 +348,7 @@ void upb_pbdecoder_reset(upb_pbdecoder *d);
const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
bool upb_pbdecoder_resetoutput(upb_pbdecoder *d, upb_sink *sink);
upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d);
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
const upb_handlers *h);
@@ -400,6 +417,9 @@ inline const DecoderMethod* Decoder::method() const {
inline void Decoder::Reset() {
upb_pbdecoder_reset(this);
}
+inline uint64_t Decoder::BytesParsed() const {
+ return upb_pbdecoder_bytesparsed(this);
+}
inline bool Decoder::ResetOutput(Sink* sink) {
return upb_pbdecoder_resetoutput(this, sink);
}
diff --git a/upb/pb/decoder.int.h b/upb/pb/decoder.int.h
index 11aa133..d0f12cc 100644
--- a/upb/pb/decoder.int.h
+++ b/upb/pb/decoder.int.h
@@ -1,3 +1,11 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2009-2014 Google Inc. See LICENSE for details.
+ * Author: Josh Haberman <jhaberman@gmail.com>
+ *
+ * Internal-only definitions for the decoder.
+ */
#ifndef UPB_DECODER_INT_H_
#define UPB_DECODER_INT_H_
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index 8a49c73..94f19e2 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -170,11 +170,10 @@ static bool putenum(void *closure, const void *handler_data, int32_t val) {
putf(p, "%s: %s", upb_fielddef_name(f), label);
endfield(p);
} else {
- CHECK(putint32(closure, handler_data, val));
+ if (!putint32(closure, handler_data, val))
+ return false;
}
return true;
-err:
- return false;
}
static void *startstr(void *closure, const void *handler_data,
@@ -182,6 +181,7 @@ static void *startstr(void *closure, const void *handler_data,
const upb_fielddef *f = handler_data;
UPB_UNUSED(size_hint);
upb_textprinter *p = closure;
+ indent(p);
putf(p, "%s: \"", upb_fielddef_name(f));
return p;
}
@@ -244,16 +244,18 @@ void upb_textprinter_reset(upb_textprinter *p, bool single_line) {
p->indent_depth_ = 0;
}
-static void onmreg(void *c, upb_handlers *h) {
- (void)c;
+static void onmreg(const void *c, upb_handlers *h) {
+ UPB_UNUSED(c);
const upb_msgdef *m = upb_handlers_msgdef(h);
+
upb_handlers_setstartmsg(h, startmsg, NULL);
upb_handlers_setendmsg(h, endmsg, NULL);
+
upb_msg_iter i;
for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
upb_fielddef *f = upb_msg_iter_field(&i);
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, f, NULL);
+ upb_handlerattr_sethandlerdata(&attr, f);
switch (upb_fielddef_type(f)) {
case UPB_TYPE_INT32:
upb_handlers_setint32(h, f, putint32, &attr);
@@ -287,9 +289,7 @@ static void onmreg(void *c, upb_handlers *h) {
upb_fielddef_istagdelim(f)
? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
: upb_fielddef_name(f);
- // TODO(haberman): add "setconsthandlerdata"? If we pass NULL for
- // cleanup then we don't need a non-const pointer.
- upb_handlerattr_sethandlerdata(&attr, (void*)name, NULL);
+ upb_handlerattr_sethandlerdata(&attr, name);
upb_handlers_setstartsubmsg(h, f, startsubmsg, &attr);
upb_handlers_setendsubmsg(h, f, endsubmsg, &attr);
break;
diff --git a/upb/refcounted.c b/upb/refcounted.c
index 455e536..4e01081 100644
--- a/upb/refcounted.c
+++ b/upb/refcounted.c
@@ -23,7 +23,6 @@
#include <setjmp.h>
#include <stdlib.h>
-uint32_t static_refcount = 1;
static void freeobj(upb_refcounted *o);
/* arch-specific atomic primitives *******************************************/
@@ -52,6 +51,27 @@ static bool atomic_dec(upb_atomic_t *a) {
Implement them or compile with UPB_THREAD_UNSAFE.
#endif
+// All static objects point to this refcount.
+// It is special-cased in ref/unref below.
+uint32_t static_refcount = -1;
+
+// We can avoid atomic ops for statically-declared objects.
+// This is a minor optimization but nice since we can avoid degrading under
+// contention in this case.
+
+static void refgroup(uint32_t *group) {
+ if (group != &static_refcount)
+ atomic_inc(group);
+}
+
+static bool unrefgroup(uint32_t *group) {
+ if (group == &static_refcount) {
+ return false;
+ } else {
+ return atomic_dec(group);
+ }
+}
+
/* Reference tracking (debug only) ********************************************/
@@ -82,7 +102,7 @@ typedef struct {
bool is_ref2;
} trackedref;
-trackedref *trackedref_new(bool is_ref2) {
+static trackedref *trackedref_new(bool is_ref2) {
trackedref *ret = malloc(sizeof(*ret));
CHECK_OOM(ret);
ret->count = 1;
@@ -319,20 +339,20 @@ UPB_NORETURN static void oom(tarjan *t) {
err(t);
}
-uint64_t trygetattr(const tarjan *t, const upb_refcounted *r) {
+static uint64_t trygetattr(const tarjan *t, const upb_refcounted *r) {
upb_value v;
return upb_inttable_lookupptr(&t->objattr, r, &v) ?
upb_value_getuint64(v) : 0;
}
-uint64_t getattr(const tarjan *t, const upb_refcounted *r) {
+static uint64_t getattr(const tarjan *t, const upb_refcounted *r) {
upb_value v;
bool found = upb_inttable_lookupptr(&t->objattr, r, &v);
UPB_ASSERT_VAR(found, found);
return upb_value_getuint64(v);
}
-void setattr(tarjan *t, const upb_refcounted *r, uint64_t attr) {
+static void setattr(tarjan *t, const upb_refcounted *r, uint64_t attr) {
upb_inttable_removeptr(&t->objattr, r, NULL);
upb_inttable_insertptr(&t->objattr, r, upb_value_uint64(attr));
}
@@ -400,7 +420,7 @@ static void set_lowlink(tarjan *t, const upb_refcounted *r, uint32_t lowlink) {
setattr(t, r, ((uint64_t)lowlink << 33) | (getattr(t, r) & 0x1FFFFFFFF));
}
-uint32_t *group(tarjan *t, upb_refcounted *r) {
+static uint32_t *group(tarjan *t, upb_refcounted *r) {
assert(color(t, r) == WHITE);
uint64_t groupnum = getattr(t, r) >> 8;
upb_value v;
@@ -480,7 +500,7 @@ static void crossref(const upb_refcounted *r, const upb_refcounted *subobj,
if (color(t, subobj) > BLACK && r->group != subobj->group) {
// Previously this ref was not reflected in subobj->group because they
// were in the same group; now that they are split a ref must be taken.
- atomic_inc(subobj->group);
+ refgroup(subobj->group);
}
}
@@ -668,7 +688,7 @@ static void release_ref2(const upb_refcounted *obj,
}
static void unref(const upb_refcounted *r) {
- if (atomic_dec(r->group)) {
+ if (unrefgroup(r->group)) {
free(r->group);
// In two passes, since release_ref2 needs a guarantee that any subobjs
@@ -720,7 +740,7 @@ void upb_refcounted_ref(const upb_refcounted *r, const void *owner) {
track(r, owner, false);
if (!r->is_frozen)
((upb_refcounted*)r)->individual_count++;
- atomic_inc(r->group);
+ refgroup(r->group);
}
void upb_refcounted_unref(const upb_refcounted *r, const void *owner) {
@@ -734,7 +754,7 @@ void upb_refcounted_ref2(const upb_refcounted *r, upb_refcounted *from) {
assert(!from->is_frozen); // Non-const pointer implies this.
track(r, from, true);
if (r->is_frozen) {
- atomic_inc(r->group);
+ refgroup(r->group);
} else {
merge((upb_refcounted*)r, from);
}
@@ -753,8 +773,8 @@ void upb_refcounted_unref2(const upb_refcounted *r, upb_refcounted *from) {
void upb_refcounted_donateref(
const upb_refcounted *r, const void *from, const void *to) {
assert(from != to);
- assert(to != NULL);
- upb_refcounted_ref(r, to);
+ if (to != NULL)
+ upb_refcounted_ref(r, to);
if (from != NULL)
upb_refcounted_unref(r, from);
}
diff --git a/upb/shim/shim.c b/upb/shim/shim.c
index 797a2d1..02da85d 100644
--- a/upb/shim/shim.c
+++ b/upb/shim/shim.c
@@ -37,8 +37,9 @@ bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
d->hasbit = hasbit;
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, d, free);
+ upb_handlerattr_sethandlerdata(&attr, d);
upb_handlerattr_setalwaysok(&attr, true);
+ upb_handlers_addcleanup(h, d, free);
#define TYPE(u, l) \
case UPB_TYPE_##u: \
diff --git a/upb/sink.h b/upb/sink.h
index d8322e1..d2bb095 100644
--- a/upb/sink.h
+++ b/upb/sink.h
@@ -476,6 +476,11 @@ inline bool Sink::EndSequence(Handlers::Selector sel) {
}
template <class T>
+BytesSink::BytesSink(const BytesHandler* handler, T* closure) {
+ Reset(handler, closure);
+}
+
+template <class T>
void BytesSink::Reset(const BytesHandler *handler, T *closure) {
upb_bytessink_reset(this, handler, closure);
}
diff --git a/upb/symtab.c b/upb/symtab.c
index 099aa8d..0269618 100644
--- a/upb/symtab.c
+++ b/upb/symtab.c
@@ -52,47 +52,35 @@ upb_symtab *upb_symtab_new(const void *owner) {
return s;
}
-const upb_def **upb_symtab_getdefs(const upb_symtab *s, upb_deftype_t type,
- const void *owner, int *n) {
- int total = upb_strtable_count(&s->symtab);
- // We may only use part of this, depending on how many symbols are of the
- // correct type.
- const upb_def **defs = malloc(sizeof(*defs) * total);
- upb_strtable_iter iter;
- upb_strtable_begin(&iter, &s->symtab);
- int i = 0;
- for(; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
- upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
- assert(def);
- if(type == UPB_DEF_ANY || def->type == type)
- defs[i++] = def;
- }
- *n = i;
- if (owner)
- for(i = 0; i < *n; i++) upb_def_ref(defs[i], owner);
- return defs;
+void upb_symtab_freeze(upb_symtab *s) {
+ assert(!upb_symtab_isfrozen(s));
+ upb_refcounted *r = UPB_UPCAST(s);
+ // The symtab does not take ref2's (see refcounted.h) on the defs, because
+ // defs cannot refer back to the table and therefore cannot create cycles. So
+ // 0 will suffice for maxdepth here.
+ bool ok = upb_refcounted_freeze(&r, 1, NULL, 0);
+ UPB_ASSERT_VAR(ok, ok);
}
-const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym,
- const void *owner) {
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
upb_value v;
upb_def *ret = upb_strtable_lookup(&s->symtab, sym, &v) ?
upb_value_getptr(v) : NULL;
- if (ret) upb_def_ref(ret, owner);
return ret;
}
-const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym,
- const void *owner) {
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
upb_value v;
upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
upb_value_getptr(v) : NULL;
- upb_msgdef *ret = NULL;
- if(def && def->type == UPB_DEF_MSG) {
- ret = upb_downcast_msgdef_mutable(def);
- upb_def_ref(def, owner);
- }
- return ret;
+ return def ? upb_dyncast_msgdef(def) : NULL;
+}
+
+const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
+ upb_value v;
+ upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
+ upb_value_getptr(v) : NULL;
+ return def ? upb_dyncast_enumdef(def) : NULL;
}
// Given a symbol and the base symbol inside which it is defined, find the
@@ -115,9 +103,8 @@ static upb_def *upb_resolvename(const upb_strtable *t,
}
const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
- const char *sym, const void *owner) {
+ const char *sym) {
upb_def *ret = upb_resolvename(&s->symtab, base, sym);
- if (ret) upb_def_ref(ret, owner);
return ret;
}
@@ -192,6 +179,7 @@ oom:
// The came_from_user stuff in particular is not tested.
bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
upb_status *status) {
+ assert(!upb_symtab_isfrozen(s));
upb_def **add_defs = NULL;
upb_strtable addtab;
if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
@@ -262,7 +250,7 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
m = upb_value_getptr(v);
} else {
// Need to find and dup the extendee from the existing symtab.
- const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname, &frozen_m);
+ const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname);
if (!frozen_m) {
upb_status_seterrf(status,
"Tried to extend message %s that does not exist "
@@ -271,7 +259,6 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
goto err;
}
m = upb_msgdef_dup(frozen_m, s);
- upb_msgdef_unref(frozen_m, &frozen_m);
if (!m) goto oom_err;
if (!upb_strtable_insert(&addtab, msgname, upb_value_ptr(m))) {
upb_msgdef_unref(m, s);
@@ -310,7 +297,7 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
for(upb_msg_begin(&j, m); !upb_msg_done(&j); upb_msg_next(&j)) {
upb_fielddef *f = upb_msg_iter_field(&j);
const char *name = upb_fielddef_subdefname(f);
- if (name) {
+ if (name && !upb_fielddef_subdef(f)) {
upb_def *subdef = upb_resolvename(&addtab, base, name);
if (subdef == NULL) {
upb_status_seterrf(
@@ -320,10 +307,6 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
goto err;
}
}
-
- if (!upb_fielddef_resolveenumdefault(f, status)) {
- goto err;
- }
}
}
@@ -380,3 +363,35 @@ err: {
assert(!upb_ok(status));
return false;
}
+
+// Iteration.
+
+static void advance_to_matching(upb_symtab_iter *iter) {
+ if (iter->type == UPB_DEF_ANY)
+ return;
+
+ while (!upb_strtable_done(&iter->iter) &&
+ iter->type != upb_symtab_iter_def(iter)->type) {
+ upb_strtable_next(&iter->iter);
+ }
+}
+
+void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
+ upb_deftype_t type) {
+ upb_strtable_begin(&iter->iter, &s->symtab);
+ iter->type = type;
+ advance_to_matching(iter);
+}
+
+void upb_symtab_next(upb_symtab_iter *iter) {
+ upb_strtable_next(&iter->iter);
+ advance_to_matching(iter);
+}
+
+bool upb_symtab_done(const upb_symtab_iter *iter) {
+ return upb_strtable_done(&iter->iter);
+}
+
+const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
+ return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
+}
diff --git a/upb/symtab.h b/upb/symtab.h
index c260671..f2baeb7 100644
--- a/upb/symtab.h
+++ b/upb/symtab.h
@@ -28,8 +28,14 @@ typedef struct upb_symtab upb_symtab;
#include "upb/def.h"
+typedef struct {
+ upb_strtable_iter iter;
+ upb_deftype_t type;
+} upb_symtab_iter;
+
#ifdef __cplusplus
+// Non-const methods in upb::SymbolTable are NOT thread-safe.
class upb::SymbolTable {
public:
// Returns a new symbol table with a single ref owned by "owner."
@@ -43,6 +49,21 @@ class upb::SymbolTable {
void DonateRef(const void *from, const void *to) const;
void CheckRef(const void *owner) const;
+ // For all lookup functions, the returned pointer is not owned by the
+ // caller; it may be invalidated by any non-const call or unref of the
+ // SymbolTable! To protect against this, take a ref if desired.
+
+ // Freezes the symbol table: prevents further modification of it.
+ // After the Freeze() operation is successful, the SymbolTable must only be
+ // accessed via a const pointer.
+ //
+ // Unlike with upb::MessageDef/upb::EnumDef/etc, freezing a SymbolTable is not
+ // a necessary step in using a SymbolTable. If you have no need for it to be
+ // immutable, there is no need to freeze it ever. However sometimes it is
+ // useful, and SymbolTables that are statically compiled into the binary are
+ // always frozen by nature.
+ void Freeze();
+
// Resolves the given symbol using the rules described in descriptor.proto,
// namely:
//
@@ -52,19 +73,17 @@ class upb::SymbolTable {
// to the root namespace).
//
// If not found, returns NULL.
- reffed_ptr<const Def> Resolve(const char* base, const char* sym) const;
+ const Def* Resolve(const char* base, const char* sym) const;
// Finds an entry in the symbol table with this exact name. If not found,
// returns NULL.
- reffed_ptr<const Def> Lookup(const char *sym) const;
- reffed_ptr<const MessageDef> LookupMessage(const char *sym) const;
+ const Def* Lookup(const char *sym) const;
+ const MessageDef* LookupMessage(const char *sym) const;
+ const EnumDef* LookupEnum(const char *sym) const;
- // Gets an array of pointers to all currently active defs in this symtab.
- // The caller owns the returned array (which is of length *n) as well as a
- // ref to each symbol inside (owned by owner). If type is UPB_DEF_ANY then
- // defs of all types are returned, otherwise only defs of the required type
- // are returned.
- const Def** GetDefs(upb_deftype_t type, const void *owner, int *n) const;
+ // TODO: introduce a C++ iterator, but make it nice and templated so that if
+ // you ask for an iterator of MessageDef the iterated elements are strongly
+ // typed as MessageDef*.
// Adds the given mutable defs to the symtab, resolving all symbols
// (including enum default values) and finalizing the defs. Only one def per
@@ -113,6 +132,9 @@ struct upb_symtab {
upb_strtable symtab;
};
+#define UPB_SYMTAB_INIT(symtab, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(refs, ref2s), symtab }
+
// Native C API.
#ifdef __cplusplus
extern "C" {
@@ -126,17 +148,31 @@ void upb_symtab_donateref(
void upb_symtab_checkref(const upb_symtab *s, const void *owner);
upb_symtab *upb_symtab_new(const void *owner);
+void upb_symtab_freeze(upb_symtab *s);
const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
- const char *sym, const void *owner);
-const upb_def *upb_symtab_lookup(
- const upb_symtab *s, const char *sym, const void *owner);
-const upb_msgdef *upb_symtab_lookupmsg(
- const upb_symtab *s, const char *sym, const void *owner);
-const upb_def **upb_symtab_getdefs(
- const upb_symtab *s, upb_deftype_t type, const void *owner, int *n);
+ const char *sym);
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym);
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
+const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym);
bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
upb_status *status);
+// upb_symtab_iter i;
+// for(upb_symtab_begin(&i, s, type); !upb_symtab_done(&i);
+// upb_symtab_next(&i)) {
+// const upb_def *def = upb_symtab_iter_def(&i);
+// // ...
+// }
+//
+// For C we don't have separate iterators for const and non-const.
+// It is the caller's responsibility to cast the upb_fielddef* to
+// const if the upb_msgdef* is const.
+void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
+ upb_deftype_t type);
+void upb_symtab_next(upb_symtab_iter *iter);
+bool upb_symtab_done(const upb_symtab_iter *iter);
+const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter);
+
#ifdef __cplusplus
} /* extern "C" */
@@ -184,23 +220,18 @@ inline void SymbolTable::CheckRef(const void *owner) const {
upb_symtab_checkref(this, owner);
}
-inline reffed_ptr<const Def> SymbolTable::Resolve(
- const char* base, const char* sym) const {
- const upb_def *def = upb_symtab_resolve(this, base, sym, &def);
- return reffed_ptr<const Def>(def, &def);
+inline void SymbolTable::Freeze() {
+ return upb_symtab_freeze(this);
}
-inline reffed_ptr<const Def> SymbolTable::Lookup(const char *sym) const {
- const upb_def *def = upb_symtab_lookup(this, sym, &def);
- return reffed_ptr<const Def>(def, &def);
+inline const Def *SymbolTable::Resolve(const char *base,
+ const char *sym) const {
+ return upb_symtab_resolve(this, base, sym);
}
-inline reffed_ptr<const MessageDef> SymbolTable::LookupMessage(
- const char *sym) const {
- const upb_msgdef *m = upb_symtab_lookupmsg(this, sym, &m);
- return reffed_ptr<const MessageDef>(m, &m);
+inline const Def* SymbolTable::Lookup(const char *sym) const {
+ return upb_symtab_lookup(this, sym);
}
-inline const Def** SymbolTable::GetDefs(
- upb_deftype_t type, const void *owner, int *n) const {
- return upb_symtab_getdefs(this, type, owner, n);
+inline const MessageDef *SymbolTable::LookupMessage(const char *sym) const {
+ return upb_symtab_lookupmsg(this, sym);
}
inline bool SymbolTable::Add(
Def*const* defs, int n, void* ref_donor, upb_status* status) {
diff --git a/upb/table.c b/upb/table.c
index 0b43fd9..c7d2a9d 100644
--- a/upb/table.c
+++ b/upb/table.c
@@ -186,16 +186,17 @@ static bool rm(upb_table *t, upb_tabkey key, upb_value *val,
}
}
-static const upb_tabent *next(const upb_table *t, const upb_tabent *e) {
- const upb_tabent *end = t->entries + upb_table_size(t);
- do { if (++e == end) return NULL; } while(e->key.num == 0);
- return e;
+static size_t next(const upb_table *t, size_t i) {
+ do {
+ if (++i >= upb_table_size(t))
+ return SIZE_MAX;
+ } while(upb_tabent_isempty(&t->entries[i]));
+
+ return i;
}
-// TODO: is calculating t->entries - 1 undefined behavior? If so find a better
-// solution.
-static const upb_tabent *begin(const upb_table *t) {
- return next(t, t->entries - 1);
+static size_t begin(const upb_table *t) {
+ return next(t, -1);
}
@@ -222,20 +223,27 @@ void upb_strtable_uninit(upb_strtable *t) {
uninit(&t->t);
}
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2) {
+ upb_strtable new_table;
+ if (!init(&new_table.t, t->t.ctype, size_lg2))
+ return false;
+ upb_strtable_iter i;
+ upb_strtable_begin(&i, t);
+ for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+ upb_strtable_insert(
+ &new_table, upb_strtable_iter_key(&i), upb_strtable_iter_value(&i));
+ }
+ upb_strtable_uninit(t);
+ *t = new_table;
+ return true;
+}
+
bool upb_strtable_insert(upb_strtable *t, const char *k, upb_value v) {
if (isfull(&t->t)) {
// Need to resize. New table of double the size, add old elements to it.
- upb_strtable new_table;
- if (!init(&new_table.t, t->t.ctype, t->t.size_lg2 + 1))
+ if (!upb_strtable_resize(t, t->t.size_lg2 + 1)) {
return false;
- upb_strtable_iter i;
- upb_strtable_begin(&i, t);
- for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
- upb_strtable_insert(
- &new_table, upb_strtable_iter_key(&i), upb_strtable_iter_value(&i));
}
- upb_strtable_uninit(t);
- *t = new_table;
}
if ((k = upb_strdup(k)) == NULL) return false;
insert(&t->t, strkey(k), v, &strhash, &streql);
@@ -256,13 +264,45 @@ bool upb_strtable_remove(upb_strtable *t, const char *key, upb_value *val) {
}
}
+// Iteration
+
+static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
+ return &i->t->t.entries[i->index];
+}
+
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
i->t = t;
- i->e = begin(&t->t);
+ i->index = begin(&t->t);
}
void upb_strtable_next(upb_strtable_iter *i) {
- i->e = next(&i->t->t, i->e);
+ i->index = next(&i->t->t, i->index);
+}
+
+bool upb_strtable_done(const upb_strtable_iter *i) {
+ return i->index >= upb_table_size(&i->t->t) ||
+ upb_tabent_isempty(str_tabent(i));
+}
+
+const char *upb_strtable_iter_key(upb_strtable_iter *i) {
+ assert(!upb_strtable_done(i));
+ return str_tabent(i)->key.str;
+}
+
+upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
+ assert(!upb_strtable_done(i));
+ return _upb_value_val(str_tabent(i)->val, i->t->t.ctype);
+}
+
+void upb_strtable_iter_setdone(upb_strtable_iter *i) {
+ i->index = SIZE_MAX;
+}
+
+bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
+ const upb_strtable_iter *i2) {
+ if (upb_strtable_done(i1) && upb_strtable_done(i2))
+ return true;
+ return i1->t == i2->t && i1->index == i2->index;
}
@@ -347,8 +387,9 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val) {
upb_table new_table;
if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1))
return false;
- const upb_tabent *e;
- for (e = begin(&t->t); e; e = next(&t->t, e)) {
+ size_t i;
+ for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
+ const upb_tabent *e = &t->t.entries[i];
upb_value v;
_upb_value_setval(&v, e->val, t->t.ctype);
insert(&new_table, e->key, v, &upb_inthash, &inteql);
@@ -479,9 +520,21 @@ void upb_inttable_compact(upb_inttable *t) {
*t = new_t;
}
+// Iteration.
+
+static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
+ assert(!i->array_part);
+ return &i->t->t.entries[i->index];
+}
+
+static _upb_value int_arrent(const upb_inttable_iter *i) {
+ assert(i->array_part);
+ return i->t->array[i->index];
+}
+
void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
i->t = t;
- i->arrkey = -1;
+ i->index = -1;
i->array_part = true;
upb_inttable_next(i);
}
@@ -489,16 +542,51 @@ void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
void upb_inttable_next(upb_inttable_iter *iter) {
const upb_inttable *t = iter->t;
if (iter->array_part) {
- for (size_t i = iter->arrkey; ++i < t->array_size; )
- if (upb_arrhas(t->array[i])) {
- iter->ptr.val = &t->array[i];
- iter->arrkey = i;
+ while (++iter->index < t->array_size) {
+ if (upb_arrhas(int_arrent(iter))) {
return;
}
+ }
iter->array_part = false;
- iter->ptr.ent = t->t.entries - 1;
+ iter->index = begin(&t->t);
+ } else {
+ iter->index = next(&t->t, iter->index);
+ }
+}
+
+bool upb_inttable_done(const upb_inttable_iter *i) {
+ if (i->array_part) {
+ return i->index >= i->t->array_size ||
+ !upb_arrhas(int_arrent(i));
+ } else {
+ return i->index >= upb_table_size(&i->t->t) ||
+ upb_tabent_isempty(int_tabent(i));
}
- iter->ptr.ent = next(&t->t, iter->ptr.ent);
+}
+
+uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
+ assert(!upb_inttable_done(i));
+ return i->array_part ? i->index : int_tabent(i)->key.num;
+}
+
+upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
+ assert(!upb_inttable_done(i));
+ return _upb_value_val(
+ i->array_part ? i->t->array[i->index] : int_tabent(i)->val,
+ i->t->t.ctype);
+}
+
+void upb_inttable_iter_setdone(upb_inttable_iter *i) {
+ i->index = SIZE_MAX;
+ i->array_part = false;
+}
+
+bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
+ const upb_inttable_iter *i2) {
+ if (upb_inttable_done(i1) && upb_inttable_done(i2))
+ return true;
+ return i1->t == i2->t && i1->index == i2->index &&
+ i1->array_part == i2->array_part;
}
#ifdef UPB_UNALIGNED_READS_OK
diff --git a/upb/table.int.h b/upb/table.int.h
index 109f76b..395ab7a 100644
--- a/upb/table.int.h
+++ b/upb/table.int.h
@@ -46,6 +46,7 @@ typedef enum {
UPB_CTYPE_CSTR = 6,
UPB_CTYPE_PTR = 7,
UPB_CTYPE_CONSTPTR = 8,
+ UPB_CTYPE_FPTR = 9,
} upb_ctype_t;
typedef union {
@@ -57,6 +58,7 @@ typedef union {
char *cstr;
void *ptr;
const void *constptr;
+ upb_func *fptr;
} _upb_value;
typedef struct {
@@ -90,6 +92,7 @@ typedef struct {
#define UPB_VALUE_INIT_CSTR(v) UPB_VALUE_INIT(v, cstr)
#define UPB_VALUE_INIT_PTR(v) UPB_VALUE_INIT(v, ptr)
#define UPB_VALUE_INIT_CONSTPTR(v) UPB_VALUE_INIT(v, constptr)
+#define UPB_VALUE_INIT_FPTR(v) UPB_VALUE_INIT(v, fptr)
// Like strdup(), which isn't always available since it's not ANSI C.
char *upb_strdup(const char *s);
@@ -138,6 +141,7 @@ FUNCS(bool, _bool, bool, UPB_CTYPE_BOOL);
FUNCS(cstr, cstr, char*, UPB_CTYPE_CSTR);
FUNCS(ptr, ptr, void*, UPB_CTYPE_PTR);
FUNCS(constptr, constptr, const void*, UPB_CTYPE_CONSTPTR);
+FUNCS(fptr, fptr, upb_func*, UPB_CTYPE_FPTR);
#undef FUNCS
@@ -302,10 +306,35 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
}
}
+// Exposed for testing only.
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2);
+
+/* Iterators ******************************************************************/
+
+// Iterators for int and string tables. We are subject to some kind of unusual
+// design constraints:
+//
+// For high-level languages:
+// - we must be able to guarantee that we don't crash or corrupt memory even if
+// the program accesses an invalidated iterator.
+//
+// For C++11 range-based for:
+// - iterators must be copyable
+// - iterators must be comparable
+// - it must be possible to construct an "end" value.
+//
+// Iteration order is undefined.
+//
+// Modifying the table invalidates iterators. upb_{str,int}table_done() is
+// guaranteed to work even on an invalidated iterator, as long as the table it
+// is iterating over has not been freed. Calling next() or accessing data from
+// an invalidated iterator yields unspecified elements from the table, but it is
+// guaranteed not to crash and to return real table elements (except when done()
+// is true).
+
/* upb_strtable_iter **********************************************************/
-// Strtable iteration. Order is undefined. Insertions invalidate iterators.
// upb_strtable_iter i;
// upb_strtable_begin(&i, t);
// for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
@@ -313,36 +342,24 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
// const upb_value val = upb_strtable_iter_value(&i);
// // ...
// }
+
typedef struct {
const upb_strtable *t;
- const upb_tabent *e;
+ size_t index;
} upb_strtable_iter;
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
void upb_strtable_next(upb_strtable_iter *i);
-UPB_INLINE bool upb_strtable_done(upb_strtable_iter *i) { return i->e == NULL; }
-UPB_INLINE const char *upb_strtable_iter_key(upb_strtable_iter *i) {
- return i->e->key.str;
-}
-UPB_INLINE upb_value upb_strtable_iter_value(upb_strtable_iter *i) {
- return _upb_value_val(i->e->val, i->t->t.ctype);
-}
-UPB_INLINE void upb_strtable_iter_copy(upb_strtable_iter *to,
- const upb_strtable_iter *from) {
- *to = *from;
-}
-UPB_INLINE void upb_strtable_iter_setdone(upb_strtable_iter *i) {
- i->e = NULL;
-}
-UPB_INLINE bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
- const upb_strtable_iter *i2) {
- return i1->e == i2->e;
-}
+bool upb_strtable_done(const upb_strtable_iter *i);
+const char *upb_strtable_iter_key(upb_strtable_iter *i);
+upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
+void upb_strtable_iter_setdone(upb_strtable_iter *i);
+bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
+ const upb_strtable_iter *i2);
/* upb_inttable_iter **********************************************************/
-// Inttable iteration. Order is undefined. Insertions invalidate iterators.
// upb_inttable_iter i;
// upb_inttable_begin(&i, t);
// for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
@@ -350,39 +367,22 @@ UPB_INLINE bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
// upb_value val = upb_inttable_iter_value(&i);
// // ...
// }
+
typedef struct {
const upb_inttable *t;
- union {
- const upb_tabent *ent; // For hash iteration.
- const _upb_value *val; // For array iteration.
- } ptr;
- uintptr_t arrkey;
+ size_t index;
bool array_part;
} upb_inttable_iter;
void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t);
void upb_inttable_next(upb_inttable_iter *i);
-UPB_INLINE bool upb_inttable_done(const upb_inttable_iter *i) {
- return i->ptr.ent == NULL;
-}
-UPB_INLINE uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
- return i->array_part ? i->arrkey : i->ptr.ent->key.num;
-}
-UPB_INLINE upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
- return _upb_value_val(
- i->array_part ? *i->ptr.val : i->ptr.ent->val, i->t->t.ctype);
-}
-UPB_INLINE void upb_inttable_iter_copy(upb_inttable_iter *to,
- const upb_inttable_iter *from) {
- *to = *from;
-}
-UPB_INLINE void upb_inttable_iter_setdone(upb_inttable_iter *i) {
- i->ptr.ent = NULL;
-}
-UPB_INLINE bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
- const upb_inttable_iter *i2) {
- return i1->ptr.ent == i2->ptr.ent;
-}
+bool upb_inttable_done(const upb_inttable_iter *i);
+uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i);
+upb_value upb_inttable_iter_value(const upb_inttable_iter *i);
+void upb_inttable_iter_setdone(upb_inttable_iter *i);
+bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
+ const upb_inttable_iter *i2);
+
#ifdef __cplusplus
} /* extern "C" */
diff --git a/upb/upb.h b/upb/upb.h
index aa109dd..c084b19 100644
--- a/upb/upb.h
+++ b/upb/upb.h
@@ -80,6 +80,8 @@
// debug mode.
#define UPB_ASSERT_VAR(var, predicate) UPB_UNUSED(var); assert(predicate)
+// Generic function type.
+typedef void upb_func();
/* Casts **********************************************************************/
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback