Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

170 lines
7.2 KiB

//
// upb - a minimalist implementation of protocol buffers.
//
// Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
// Author: Josh Haberman <jhaberman@gmail.com>
//
// A bridge between upb and proto2, allows populating proto2 generated
// classes using upb's parser, translating between descriptors and defs, etc.
//
// This is designed to be able to be compiled against either the open-source
// version of protocol buffers or the Google-internal proto2. The two are
// the same in most ways, but live in different namespaces (proto2 vs
// google::protobuf) and have a few other more minor differences.
//
// The bridge gives you a lot of control over which fields will be written to
// the message (fields that are not written will just be skipped), and whether
// unknown fields are written to the UnknownFieldSet. This can save a lot of
// work if the client only cares about some subset of the fields.
//
// Example usage:
//
// // Build a def that will have all fields and parse just like proto2 would.
// const upb::MessageDef* md = upb::proto2_bridge::NewMessageDef(&MyProto());
//
// // JIT the parser; should only be done once ahead-of-time.
// upb::Handlers* handlers = upb::NewHandlersForMessage(md);
// upb::DecoderPlan* plan = upb::DecoderPlan::New(handlers);
// handlers->Unref();
//
// // The actual parsing.
// MyProto proto;
// upb::Decoder decoder;
// upb::StringSource source(buf, len);
// decoder.ResetPlan(plan, 0);
// decoder.ResetInput(source.AllBytes(), &proto);
// CHECK(decoder.Decode() == UPB_OK) << decoder.status();
//
// To parse only one field and skip all others:
//
// const upb::MessageDef* md =
// upb::proto2_bridge::NewEmptyMessageDef(MyProto().GetPrototype());
// upb::proto2_bridge::AddFieldDef(
// MyProto::descriptor()->FindFieldByName("my_field"), md);
// upb::Finalize(md);
//
// // Now continue with "JIT the parser" from above.
//
// Note that there is currently no support for
// CodedInputStream::SetExtensionRegistry(), which allows specifying a separate
// DescriptorPool and MessageFactory for extensions. Since this is a property
// of the input in proto2, it's difficult to build a plan ahead-of-time that
// can properly support this. If it's an important use case, the caller should
// probably build a upb plan explicitly.
#ifndef UPB_PROTO2_BRIDGE
#define UPB_PROTO2_BRIDGE
#include <vector>
namespace google {
namespace protobuf {
class Descriptor;
class EnumDescriptor;
class FieldDescriptor;
class FileDescriptor;
class Message;
} // namespace google
} // namespace protobuf
namespace proto2 {
class Descriptor;
class EnumDescriptor;
class FieldDescriptor;
class FileDescriptor;
class Message;
} // namespace proto2
namespace upb {
class Def;
class FieldDef;
class MessageDef;
namespace proto2_bridge {
// Unfinalized defs ////////////////////////////////////////////////////////////
// Creating of UNFINALIZED defs. All of these functions return defs that are
// still mutable and have not been finalized. They must be finalized before
// using them to parse anything. This is useful if you want more control over
// the process of constructing defs, eg. to add the specific set of fields you
// care about.
// Creates a new upb::MessageDef that corresponds to the type in the given
// prototype message. The MessageDef will not have any fields added to it.
upb::MessageDef *NewEmptyMessageDef(const proto2::Message& m, void *owner);
upb::MessageDef *NewEmptyMessageDef(const google::protobuf::Message& desc,
void *owner);
// Adds a new upb::FieldDef to the given MessageDef corresponding to the given
// FieldDescriptor. The FieldDef will be given an accessor and offset so that
// it can be used to read and write data into the proto2::Message classes.
// The given MessageDef must have been constructed with NewEmptyDefForMessage()
// and f->containing_type() must correspond to the message that was used.
//
// Any submessage, group, or enum fields will be given symbolic references to
// the subtype, which must be resolved before the MessageDef can be finalized.
//
// On success, returns the FieldDef that was added (caller does not own a ref).
// If an existing field had the same name or number, returns NULL.
upb::FieldDef* AddFieldDef(const proto2::FieldDescriptor* f,
upb::MessageDef* md);
upb::FieldDef* AddFieldDef(const google::protobuf::FieldDescriptor* f,
upb::MessageDef* md);
// Given a MessageDef that was constructed with NewEmptyDefForMessage(), adds
// FieldDefs for all fields defined in the original message, but not for any
// extensions or unknown fields. The given MessageDef must not have any fields
// that have the same name or number as any of the fields we are adding (the
// easiest way to guarantee this is to start with an empty MessageDef).
//
// Returns true on success or false if any of the fields could not be added.
void AddAllFields(upb::MessageDef* md);
// TODO(haberman): Add:
// // Adds a handler that will store unknown fields in the UnknownFieldSet.
// void AddUnknownFieldHandler(upb::MessageDef* md);
// Returns a new upb::MessageDef that contains handlers for all fields, unknown
// fields, and any extensions in the descriptor's pool. The resulting
// def/handlers should be equivalent to the generated code constructed by the
// protobuf compiler (or the code in DynamicMessage) for the given type.
// The subdefs for message/enum fields (if any) will be referenced symbolically,
// and will need to be resolved before being finalized.
//
// TODO(haberman): Add missing support (LazyField, MessageSet, and extensions).
//
// TODO(haberman): possibly add a similar function that lets you supply a
// separate DescriptorPool and MessageFactory for extensions, to support
// proto2's io::CodedInputStream::SetExtensionRegistry().
upb::MessageDef* NewFullMessageDef(const proto2::Message& m, void *owner);
upb::MessageDef* NewFullMessageDef(const google::protobuf::Message& m,
void *owner);
// Returns a new upb::EnumDef that corresponds to the given EnumDescriptor.
// Caller owns a ref on the returned EnumDef.
upb::EnumDef* NewEnumDef(const proto2::EnumDescriptor* desc, void *owner);
upb::EnumDef* NewEnumDef(const google::protobuf::EnumDescriptor* desc,
void *owner);
// Finalized defs //////////////////////////////////////////////////////////////
// These functions return FINALIZED defs, meaning that they are immutable and
// ready for use. Since they are immutable you cannot make any further changes
// to eg. the set of fields, but these functions are more convenient if you
// simply want to parse a message exactly how the built-in proto2 parser would.
// Creates a returns a finalized MessageDef for the give message and its entire
// type tree that will include all fields and unknown handlers (ie. it will
// parse just like proto2 would).
const upb::MessageDef* NewFinalMessageDef(const proto2::Message& m,
void *owner);
const upb::MessageDef* NewFinalMessageDef(const google::protobuf::Message& m,
void *owner);
} // namespace proto2_bridge
} // namespace upb
#endif