#include <google/protobuf/message.h>
namespace google::protobuf
假设您有一个消息定义为:
message Foo {
optional string text = 1;
repeated int32 numbers = 2;
}
然后,如果你使用 protocol编译器从上面的定义生成一个类,你可以这样使用它:
std::string data; // Will store a serialized version of the message.
{
// Create a message and serialize it.
Foo foo;
foo.set_text("Hello World!");
foo.add_numbers(1);
foo.add_numbers(5);
foo.add_numbers(42);
foo.SerializeToString(&data);
}
{
// Parse the serialized message and check that it contains the
// correct data.
Foo foo;
foo.ParseFromString(data);
assert(foo.text() == "Hello World!");
assert(foo.numbers_size() == 3);
assert(foo.numbers(0) == 1);
assert(foo.numbers(1) == 5);
assert(foo.numbers(2) == 42);
}
{
// Same as the last block, but do it dynamically via the Message
// reflection interface.
Message* foo = new Foo;
const Descriptor* descriptor = foo->GetDescriptor();
// Get the descriptors for the fields we're interested in and verify
// their types.
const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
assert(text_field != nullptr);
assert(text_field->type() == FieldDescriptor::TYPE_STRING);
assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
const FieldDescriptor* numbers_field = descriptor->
FindFieldByName("numbers");
assert(numbers_field != nullptr);
assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
// Parse the message.
foo->ParseFromString(data);
// Use the reflection interface to examine the contents.
const Reflection* reflection = foo->GetReflection();
assert(reflection->GetString(*foo, text_field) == "Hello World!");
assert(reflection->FieldSize(*foo, numbers_field) == 3);
assert(reflection->GetRepeatedInt32(*foo, numbers_field, 0) == 1);
assert(reflection->GetRepeatedInt32(*foo, numbers_field, 1) == 5);
assert(reflection->GetRepeatedInt32(*foo, numbers_field, 2) == 42);
delete foo;
}
这个文件中的类
Metadata:用于保存消息元数据的容器。
Message:协议消息的抽象接口。
Reflection:此接口包含可用于动态访问和修改协议消息字段的方法。
MessageFactory:消息对象工厂的抽象接口。
文件成员
以下定义不是任何类的一部分。
//尝试将此消息向下转换为生成的消息类型
template const T * DynamicCastToGenerated(const Message * from)
template T * DynamicCastToGenerated(Message* from)
//调用此函数以确保此消息的反射被链接到二进制文件
template void LinkMessageReflection ()
//调用方式
google::protobuf::LinkMessageReflection<FooMessage>();
//这将确保以下查找成功:
DescriptorPool::generated_pool()->FindMessageTypeByName("FooMessage");
const RepeatedPtrField< std::string > &
Reflection::GetRepeatedPtrFieldInternal< std::string >(const Message & message, const FieldDescriptor * field) const
RepeatedPtrField< std::string > *
Reflection::MutableRepeatedPtrFieldInternal< std::string >(Message * message, const FieldDescriptor * field) const
结构元数据
#include <google/protobuf/message.h>
namespace google::protobuf
用于保存消息元数据的容器。
//成员:
const Descriptor * descriptor
const Reflection * reflection
class Message: public MessageLite
#include <google/protobuf/message.h>
namespace google::protobuf
协议消息的抽象接口。
另请参见MessageLite,它包含大多数日常操作,Message类在此基础上添加了描述符(descriptors)和反射reflection()。
用户不能从这个类派生。只有protocol编译器和内部库允许创建子类。
constexpr Message()
protected virtual Metadata
//获取一个包含消息元数据的结构体,该结构体依次用于实现上面的GetDescriptor()和GetReflection()。
GetMetadata() const = 0
protected explicit Message(Arena * arena)
protected static uint64 GetInvariantPerBuild(uint64 salt)
//基本操作
//Construct a new instance of the same type.
virtual Message * New() const = 0
//Construct a new instance on the arena.
virtual Message * New(Arena * arena) const
//Make this message into a copy of the given message.
virtual void CopyFrom(const Message & from)
//Merge the fields from the given message into this message.
virtual void MergeFrom(const Message & from)
//Verifies that IsInitialized() returns true.
void CheckInitialized() const
//Slowly build a list of all required fields that are not set. more...
void FindInitializationErrors(std::vector< std::string > * errors) const
//Like FindInitializationErrors, but joins all the strings, delimited by commas, and //returns them.
virtual std::string InitializationErrorString() const
//Clears all unknown fields from this message and all embedded messages.
virtual void DiscardUnknownFields()
//Computes (an estimate of) the total number of bytes currently used for storing the //message in memory.
virtual size_t SpaceUsedLong() const
int SpaceUsed() const
调试和测试
//Generates a human readable form of this message, useful for debugging and other purposes.
std::string DebugString() const
//Like DebugString(), but with less whitespace.
std::string ShortDebugString() const
//Like DebugString(), but do not escape UTF-8 byte sequences.
std::string Utf8DebugString() const
//Convenience function useful in GDB. Prints DebugString() to stdout.
void PrintDebugString() const
基于反射的方法
这些方法在MessageLite中是纯虚拟的,但是Message提供了基于反射的默认实现。
//Get the name of this message type, e.g. "foo.bar.BazProto".
virtual std::string GetTypeName() const
//Clear all fields of the message and set them to their default values.
virtual void Clear()
//Returns whether all required fields have been set.
virtual bool IsInitialized() const
//If |other| is the exact same class as this, calls MergeFrom(). more...
virtual void CheckTypeAndMergeFrom(const MessageLite & other)
//Reflective parser.
virtual const char * _InternalParse(const char * ptr, internal::ParseContext * ctx)
//Computes the serialized size of the message.
virtual size_t ByteSizeLong() const
//Fast path when conditions match
virtual uint8 * _InternalSerialize(uint8 * ptr, io::EpsCopyOutputStream * stream) const
//自省
//Get a non-owning pointer to a Descriptor for this message's type.
const Descriptor * GetDescriptor() const
//Get a non-owning pointer to the Reflection interface for this Message, which can be used to read and modify the fields of the Message dynamically (in other words, without knowing the message type at compile time).
const Reflection * GetReflection() const
Reflection类
#include <google/protobuf/message.h>
命名空间google::protobuf
此接口包含可用于动态访问和修改协议消息字段的方法。
它们的语义类似于protocol编译器生成的访问器。
要获取给定消息的反射,请调用Message:: getrereflect()。
该接口与Message分离只是出于效率的考虑;Message的绝大多数实现将共享相同的Reflection实现(GeneratedMessageReflection,在generated_message.h中定义),并且特定类的所有消息应该共享相同的Reflection对象。
这些方法有几种不正确的使用方式。例如,以下任何条件都会导致未定义的结果:
FieldDescriptor不是此消息类型的字段。
所调用的方法不适合字段的类型。对于FieldDescriptor::TYPE_*中的每个字段类型,只有一个Get*()方法、一个Set*()方法和一个Add*()方法对该类型有效。
在重复字段上调用单个字段的Get*()或Set*()方法。
在非重复字段上调用GetRepeated*(), SetRepeated*()或Add*()。
传递给任何方法的Message对象都不是这个Reflection对象的正确类型(即Message . getreflection () != Reflection)。