// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: [email protected] (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // Defines Message, the abstract interface implemented by non-lite // protocol message objects. Although it's possible to implement this // interface manually, most users will use the protocol compiler to // generate implementations. // // Example usage: // // Say you have a message defined as: // // message Foo { // optional string text = 1; // repeated int32 numbers = 2; // } // // Then, if you used the protocol compiler to generate a class from the above // definition, you could use it like so: // // 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; // } #ifndef GOOGLE_PROTOBUF_MESSAGE_H__ #define GOOGLE_PROTOBUF_MESSAGE_H__ #include <iosfwd> #include <string> #include <type_traits> #include <vector> #include <google/protobuf/stubs/casts.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/arena.h> #include <google/protobuf/port.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/generated_message_reflection.h> #include <google/protobuf/generated_message_util.h> #include <google/protobuf/map.h> // TODO(b/211442718): cleanup #include <google/protobuf/message_lite.h> // Must be included last. #include <google/protobuf/port_def.inc> #ifdef SWIG #error "You cannot SWIG proto headers" #endif namespace google { namespace protobuf { // Defined in this file. class Message; class Reflection; class MessageFactory; // Defined in other files. class AssignDescriptorsHelper; class DynamicMessageFactory; class GeneratedMessageReflectionTestHelper; class MapKey; class MapValueConstRef; class MapValueRef; class MapIterator; class MapReflectionTester; namespace internal { struct DescriptorTable; class MapFieldBase; class SwapFieldHelper; class CachedSize; } // namespace internal class UnknownFieldSet; // unknown_field_set.h namespace io { class ZeroCopyInputStream; // zero_copy_stream.h class ZeroCopyOutputStream; // zero_copy_stream.h class CodedInputStream; // coded_stream.h class CodedOutputStream; // coded_stream.h } // namespace io namespace python { class MapReflectionFriend; // scalar_map_container.h class MessageReflectionFriend; } // namespace python namespace expr { class CelMapReflectionFriend; // field_backed_map_impl.cc } namespace internal { class MapFieldPrinterHelper; // text_format.cc } namespace util { class MessageDifferencer; } namespace internal { class ReflectionAccessor; // message.cc class ReflectionOps; // reflection_ops.h class MapKeySorter; // wire_format.cc class WireFormat; // wire_format.h class MapFieldReflectionTest; // map_test.cc } // namespace internal template <typename T> class RepeatedField; // repeated_field.h template <typename T> class RepeatedPtrField; // repeated_field.h // A container to hold message metadata. struct Metadata { … }; namespace internal { template <class To> inline To* GetPointerAtOffset(Message* message, uint32_t offset) { … } template <class To> const To* GetConstPointerAtOffset(const Message* message, uint32_t offset) { … } template <class To> const To& GetConstRefAtOffset(const Message& message, uint32_t offset) { … } bool CreateUnknownEnumValues(const FieldDescriptor* field); // Returns true if "message" is a descendant of "root". PROTOBUF_EXPORT bool IsDescendant(Message& root, const Message& message); } // namespace internal // Abstract interface for protocol messages. // // See also MessageLite, which contains most every-day operations. Message // adds descriptors and reflection on top of that. // // The methods of this class that are virtual but not pure-virtual have // default implementations based on reflection. Message classes which are // optimized for speed will want to override these with faster implementations, // but classes optimized for code size may be happy with keeping them. See // the optimize_for option in descriptor.proto. // // Users must not derive from this class. Only the protocol compiler and // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT Message : public MessageLite { … }; namespace internal { // Forward-declare interfaces used to implement RepeatedFieldRef. // These are protobuf internals that users shouldn't care about. class RepeatedFieldAccessor; } // namespace internal // Forward-declare RepeatedFieldRef templates. The second type parameter is // used for SFINAE tricks. Users should ignore it. template <typename T, typename Enable = void> class RepeatedFieldRef; template <typename T, typename Enable = void> class MutableRepeatedFieldRef; // This interface contains methods that can be used to dynamically access // and modify the fields of a protocol message. Their semantics are // similar to the accessors the protocol compiler generates. // // To get the Reflection for a given Message, call Message::GetReflection(). // // This interface is separate from Message only for efficiency reasons; // the vast majority of implementations of Message will share the same // implementation of Reflection (GeneratedMessageReflection, // defined in generated_message.h), and all Messages of a particular class // should share the same Reflection object (though you should not rely on // the latter fact). // // There are several ways that these methods can be used incorrectly. For // example, any of the following conditions will lead to undefined // results (probably assertion failures): // - The FieldDescriptor is not a field of this message type. // - The method called is not appropriate for the field's type. For // each field type in FieldDescriptor::TYPE_*, there is only one // Get*() method, one Set*() method, and one Add*() method that is // valid for that type. It should be obvious which (except maybe // for TYPE_BYTES, which are represented using strings in C++). // - A Get*() or Set*() method for singular fields is called on a repeated // field. // - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated // field. // - The Message object passed to any method is not of the right type for // this Reflection object (i.e. message.GetReflection() != reflection). // // You might wonder why there is not any abstract representation for a field // of arbitrary type. E.g., why isn't there just a "GetField()" method that // returns "const Field&", where "Field" is some class with accessors like // "GetInt32Value()". The problem is that someone would have to deal with // allocating these Field objects. For generated message classes, having to // allocate space for an additional object to wrap every field would at least // double the message's memory footprint, probably worse. Allocating the // objects on-demand, on the other hand, would be expensive and prone to // memory leaks. So, instead we ended up with this flat interface. class PROTOBUF_EXPORT Reflection final { … }; // Abstract interface for a factory for message objects. class PROTOBUF_EXPORT MessageFactory { … }; #define DECLARE_GET_REPEATED_FIELD … DECLARE_GET_REPEATED_FIELD(int32_t) DECLARE_GET_REPEATED_FIELD(int64_t) DECLARE_GET_REPEATED_FIELD(uint32_t) DECLARE_GET_REPEATED_FIELD(uint64_t) DECLARE_GET_REPEATED_FIELD(float) DECLARE_GET_REPEATED_FIELD(double) DECLARE_GET_REPEATED_FIELD(bool) #undef DECLARE_GET_REPEATED_FIELD // Tries to downcast this message to a generated message type. Returns nullptr // if this class is not an instance of T. This works even if RTTI is disabled. // // This also has the effect of creating a strong reference to T that will // prevent the linker from stripping it out at link time. This can be important // if you are using a DynamicMessageFactory that delegates to the generated // factory. template <typename T> const T* DynamicCastToGenerated(const Message* from) { … } template <typename T> T* DynamicCastToGenerated(Message* from) { … } // Call this function to ensure that this message's reflection is linked into // the binary: // // google::protobuf::LinkMessageReflection<pkg::FooMessage>(); // // This will ensure that the following lookup will succeed: // // DescriptorPool::generated_pool()->FindMessageTypeByName("pkg.FooMessage"); // // As a side-effect, it will also guarantee that anything else from the same // .proto file will also be available for lookup in the generated pool. // // This function does not actually register the message, so it does not need // to be called before the lookup. However it does need to occur in a function // that cannot be stripped from the binary (ie. it must be reachable from main). // // Best practice is to call this function as close as possible to where the // reflection is actually needed. This function is very cheap to call, so you // should not need to worry about its runtime overhead except in the tightest // of loops (on x86-64 it compiles into two "mov" instructions). template <typename T> void LinkMessageReflection() { … } // ============================================================================= // Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide // specializations for <std::string>, <StringPieceField> and <Message> and // handle everything else with the default template which will match any type // having a method with signature "static const google::protobuf::Descriptor* // descriptor()". Such a type presumably is a descendant of google::protobuf::Message. template <> inline const RepeatedPtrField<std::string>& Reflection::GetRepeatedPtrFieldInternal<std::string>( const Message& message, const FieldDescriptor* field) const { … } template <> inline RepeatedPtrField<std::string>* Reflection::MutableRepeatedPtrFieldInternal<std::string>( Message* message, const FieldDescriptor* field) const { … } // ----- template <> inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrFieldInternal( const Message& message, const FieldDescriptor* field) const { … } template <> inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrFieldInternal( Message* message, const FieldDescriptor* field) const { … } template <typename PB> inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrFieldInternal( const Message& message, const FieldDescriptor* field) const { … } template <typename PB> inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrFieldInternal( Message* message, const FieldDescriptor* field) const { … } template <typename Type> const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const { … } uint32_t Reflection::GetOneofCase( const Message& message, const OneofDescriptor* oneof_descriptor) const { … } bool Reflection::HasOneofField(const Message& message, const FieldDescriptor* field) const { … } template <typename Type> const Type& Reflection::GetRaw(const Message& message, const FieldDescriptor* field) const { … } } // namespace protobuf } // namespace google #include <google/protobuf/port_undef.inc> #endif // GOOGLE_PROTOBUF_MESSAGE_H__