1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #ifndef GOOGLE_PROTOBUF_ANY_H__ 32 #define GOOGLE_PROTOBUF_ANY_H__ 33 34 #include <string> 35 36 #include <google/protobuf/stubs/common.h> 37 #include <google/protobuf/arenastring.h> 38 #include <google/protobuf/message_lite.h> 39 40 #include <google/protobuf/port_def.inc> 41 42 namespace google { 43 namespace protobuf { 44 45 class FieldDescriptor; 46 class Message; 47 48 namespace internal { 49 50 extern const char kAnyFullTypeName[]; // "google.protobuf.Any". 51 extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/". 52 extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". 53 54 std::string GetTypeUrl(StringPiece message_name, 55 StringPiece type_url_prefix); 56 57 // Helper class used to implement google::protobuf::Any. 58 class PROTOBUF_EXPORT AnyMetadata { 59 typedef ArenaStringPtr UrlType; 60 typedef ArenaStringPtr ValueType; 61 public: 62 // AnyMetadata does not take ownership of "type_url" and "value". 63 AnyMetadata(UrlType* type_url, ValueType* value); 64 65 // Packs a message using the default type URL prefix: "type.googleapis.com". 66 // The resulted type URL will be "type.googleapis.com/<message_full_name>". 67 template <typename T> PackFrom(const T & message)68 void PackFrom(const T& message) { 69 InternalPackFrom(message, kTypeGoogleApisComPrefix, T::FullMessageName()); 70 } 71 72 void PackFrom(const Message& message); 73 74 // Packs a message using the given type URL prefix. The type URL will be 75 // constructed by concatenating the message type's full name to the prefix 76 // with an optional "/" separator if the prefix doesn't already end up "/". 77 // For example, both PackFrom(message, "type.googleapis.com") and 78 // PackFrom(message, "type.googleapis.com/") yield the same result type 79 // URL: "type.googleapis.com/<message_full_name>". 80 template <typename T> PackFrom(const T & message,StringPiece type_url_prefix)81 void PackFrom(const T& message, StringPiece type_url_prefix) { 82 InternalPackFrom(message, type_url_prefix, T::FullMessageName()); 83 } 84 85 void PackFrom(const Message& message, const std::string& type_url_prefix); 86 87 // Unpacks the payload into the given message. Returns false if the message's 88 // type doesn't match the type specified in the type URL (i.e., the full 89 // name after the last "/" of the type URL doesn't match the message's actual 90 // full name) or parsing the payload has failed. 91 template <typename T> UnpackTo(T * message)92 bool UnpackTo(T* message) const { 93 return InternalUnpackTo(T::FullMessageName(), message); 94 } 95 96 bool UnpackTo(Message* message) const; 97 98 // Checks whether the type specified in the type URL matches the given type. 99 // A type is consdiered matching if its full name matches the full name after 100 // the last "/" in the type URL. 101 template <typename T> Is()102 bool Is() const { 103 return InternalIs(T::FullMessageName()); 104 } 105 106 private: 107 void InternalPackFrom(const MessageLite& message, 108 StringPiece type_url_prefix, 109 StringPiece type_name); 110 bool InternalUnpackTo(StringPiece type_name, 111 MessageLite* message) const; 112 bool InternalIs(StringPiece type_name) const; 113 114 UrlType* type_url_; 115 ValueType* value_; 116 117 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata); 118 }; 119 120 // Get the proto type name from Any::type_url value. For example, passing 121 // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in 122 // *full_type_name. Returns false if the type_url does not have a "/" 123 // in the type url separating the full type name. 124 // 125 // NOTE: this function is available publicly as: 126 // google::protobuf::Any() // static method on the generated message type. 127 bool ParseAnyTypeUrl(const std::string& type_url, std::string* full_type_name); 128 129 // Get the proto type name and prefix from Any::type_url value. For example, 130 // passing "type.googleapis.com/rpc.QueryOrigin" will return 131 // "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in 132 // *full_type_name. Returns false if the type_url does not have a "/" in the 133 // type url separating the full type name. 134 bool ParseAnyTypeUrl(const std::string& type_url, std::string* url_prefix, 135 std::string* full_type_name); 136 137 // See if message is of type google.protobuf.Any, if so, return the descriptors 138 // for "type_url" and "value" fields. 139 bool GetAnyFieldDescriptors(const Message& message, 140 const FieldDescriptor** type_url_field, 141 const FieldDescriptor** value_field); 142 143 } // namespace internal 144 } // namespace protobuf 145 } // namespace google 146 147 #include <google/protobuf/port_undef.inc> 148 149 #endif // GOOGLE_PROTOBUF_ANY_H__ 150