From ce9bba3cb5409844f8f3d7dcc235a9ea30cad090 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 20 Dec 2013 17:40:40 -0800 Subject: Sync from Google-internal development. --- upb/descriptor/reader.h | 135 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 33 deletions(-) (limited to 'upb/descriptor/reader.h') diff --git a/upb/descriptor/reader.h b/upb/descriptor/reader.h index d00830b..f9d0046 100644 --- a/upb/descriptor/reader.h +++ b/upb/descriptor/reader.h @@ -11,7 +11,44 @@ #ifndef UPB_DESCRIPTOR_H #define UPB_DESCRIPTOR_H -#include "upb/handlers.h" +#include "upb/sink.h" + +#ifdef __cplusplus +namespace upb { +namespace descriptor { +class Reader; +} // namespace descriptor +} // namespace upb + +typedef upb::descriptor::Reader upb_descreader; +#else +struct upb_descreader; +typedef struct upb_descreader upb_descreader; +#endif + +// Internal-only structs used by Reader. + +// upb_deflist is an internal-only dynamic array for storing a growing list of +// upb_defs. +typedef struct { + UPB_PRIVATE_FOR_CPP + upb_def **defs; + size_t len; + size_t size; + bool owned; +} upb_deflist; + +// We keep a stack of all the messages scopes we are currently in, as well as +// the top-level file scope. This is necessary to correctly qualify the +// definitions that are contained inside. "name" tracks the name of the +// message or package (a bare name -- not qualified by any enclosing scopes). +typedef struct { + UPB_PRIVATE_FOR_CPP + char *name; + // Index of the first def that is under this scope. For msgdefs, the + // msgdef itself is at start-1. + int start; +} upb_descreader_frame; // The maximum number of nested declarations that are allowed, ie. // message Foo { @@ -26,55 +63,87 @@ #define UPB_MAX_MESSAGE_NESTING 64 #ifdef __cplusplus -namespace upb { -namespace descriptor { -// Frame type that accumulates defs as they are being built from a descriptor -// according to the descriptor.proto schema. -class Reader; - -// Gets the array of defs that have been parsed and removes them from the -// descreader. Ownership of the defs is passed to the caller using the given -// owner), but the ownership of the returned array is retained and is -// invalidated by any other call into the descreader. The defs will not have -// been resolved, and are ready to be added to a symtab. -inline upb::Def** GetDefs(Reader* r, void* owner, int* n); +// Class that receives descriptor data according to the descriptor.proto schema +// and use it to build upb::Defs corresponding to that schema. +class upb::descriptor::Reader { + public: + // These handlers must have come from NewHandlers() and must outlive the + // Reader. + // + // TODO: generate the handlers statically (like we do with the + // descriptor.proto defs) so that there is no need to pass this parameter (or + // to build/memory-manage the handlers at runtime at all). Unfortunately this + // is a bit tricky to implement for Handlers, but necessary to simplify this + // interface. + Reader(const Handlers* handlers, Status* status); + ~Reader(); + + // Resets the reader's state and discards any defs it may have built. + void Reset(); + + // The reader's input; this is where descriptor.proto data should be sent. + Sink* input(); + + // Returns an array of all defs that have been parsed, and transfers ownership + // of them to "owner". The number of defs is stored in *n. Ownership of the + // returned array is retained and is invalidated by any other call into + // Reader. + // + // These defs are not frozen or resolved; they are ready to be added to a + // symtab. + upb::Def** GetDefs(void* owner, int* n); + + // Builds and returns handlers for the reader, owned by "owner." + static Handlers* NewHandlers(const void* owner); + + private: +#else +struct upb_descreader { +#endif + char sink[sizeof(upb_sink)]; + upb_deflist defs; + upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING]; + int stack_len; -// Gets the handlers for reading a FileDescriptorSet, which builds defs and -// accumulates them in a Reader object (which the handlers use as their -// FrameType). -inline const upb::Handlers* GetReaderHandlers(const void* owner); + uint32_t number; + char *name; + bool saw_number; + bool saw_name; -} // namespace descriptor -} // namespace upb + char *default_string; -typedef upb::descriptor::Reader upb_descreader; + upb_fielddef *f; +}; +#ifdef __cplusplus extern "C" { -#else -struct upb_descreader; -typedef struct upb_descreader upb_descreader; #endif // C API. -const upb_frametype *upb_descreader_getframetype(); +void upb_descreader_init(upb_descreader *r, const upb_handlers *handlers, + upb_status *status); +void upb_descreader_uninit(upb_descreader *r); +void upb_descreader_reset(upb_descreader *r); +upb_sink *upb_descreader_input(upb_descreader *r); upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n); -const upb_handlers *upb_descreader_gethandlers(const void *owner); - - -// C++ implementation details. ///////////////////////////////////////////////// +const upb_handlers *upb_descreader_newhandlers(const void *owner); #ifdef __cplusplus } // extern "C" -namespace upb { +// C++ implementation details. ///////////////////////////////////////////////// +namespace upb { namespace descriptor { -inline upb::Def** GetDefs(Reader* r, void* owner, int* n) { - return upb_descreader_getdefs(r, owner, n); +inline Reader::Reader(const Handlers *h, Status *s) { + upb_descreader_init(this, h, s); } -inline const upb::Handlers* GetReaderHandlers(const void* owner) { - return upb_descreader_gethandlers(owner); +inline Reader::~Reader() { upb_descreader_uninit(this); } +inline void Reader::Reset() { upb_descreader_reset(this); } +inline Sink* Reader::input() { return upb_descreader_input(this); } +inline upb::Def** Reader::GetDefs(void* owner, int* n) { + return upb_descreader_getdefs(this, owner, n); } } // namespace descriptor } // namespace upb -- cgit v1.2.3