• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include <cstdlib>
9 #include <string>
10 
11 #include "absl/strings/cord.h"
12 #include "absl/strings/match.h"
13 #include "absl/strings/str_cat.h"
14 #include "absl/strings/string_view.h"
15 #include "google/protobuf/any.h"
16 #include "google/protobuf/generated_message_util.h"
17 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
18 #include "google/protobuf/message_lite.h"
19 
20 namespace google {
21 namespace protobuf {
22 namespace internal {
23 
24 using UrlType = std::string;
25 using ValueType = std::string;
26 
27 const char kAnyFullTypeName[] = "google.protobuf.Any";
28 const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
29 const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
30 
GetTypeUrl(absl::string_view message_name,absl::string_view type_url_prefix)31 std::string GetTypeUrl(absl::string_view message_name,
32                        absl::string_view type_url_prefix) {
33   if (!type_url_prefix.empty() &&
34       type_url_prefix[type_url_prefix.size() - 1] == '/') {
35     return absl::StrCat(type_url_prefix, message_name);
36   } else {
37     return absl::StrCat(type_url_prefix, "/", message_name);
38   }
39 }
40 
EndsWithTypeName(absl::string_view type_url,absl::string_view type_name)41 bool EndsWithTypeName(absl::string_view type_url, absl::string_view type_name) {
42   return type_url.size() > type_name.size() &&
43          type_url[type_url.size() - type_name.size() - 1] == '/' &&
44          absl::EndsWith(type_url, type_name);
45 }
46 
InternalPackFromLite(const MessageLite & message,absl::string_view type_url_prefix,absl::string_view type_name,UrlType * dst_url,ValueType * dst_value)47 bool InternalPackFromLite(const MessageLite& message,
48                           absl::string_view type_url_prefix,
49                           absl::string_view type_name, UrlType* dst_url,
50                           ValueType* dst_value) {
51   *dst_url = GetTypeUrl(type_name, type_url_prefix);
52   return message.SerializeToString(dst_value);
53 }
54 
InternalUnpackToLite(absl::string_view type_name,absl::string_view type_url,const ValueType & value,MessageLite * dst_message)55 bool InternalUnpackToLite(absl::string_view type_name,
56                           absl::string_view type_url, const ValueType& value,
57                           MessageLite* dst_message) {
58   if (!InternalIsLite(type_name, type_url)) {
59     return false;
60   }
61   return dst_message->ParseFromString(value);
62 }
63 
InternalIsLite(absl::string_view type_name,absl::string_view type_url)64 bool InternalIsLite(absl::string_view type_name, absl::string_view type_url) {
65   return EndsWithTypeName(type_url, type_name);
66 }
67 
ParseAnyTypeUrl(absl::string_view type_url,std::string * url_prefix,std::string * full_type_name)68 bool ParseAnyTypeUrl(absl::string_view type_url, std::string* url_prefix,
69                      std::string* full_type_name) {
70   size_t pos = type_url.find_last_of('/');
71   if (pos == std::string::npos || pos + 1 == type_url.size()) {
72     return false;
73   }
74   if (url_prefix) {
75     *url_prefix = std::string(type_url.substr(0, pos + 1));
76   }
77   *full_type_name = std::string(type_url.substr(pos + 1));
78   return true;
79 }
80 
ParseAnyTypeUrl(absl::string_view type_url,std::string * full_type_name)81 bool ParseAnyTypeUrl(absl::string_view type_url, std::string* full_type_name) {
82   return ParseAnyTypeUrl(type_url, nullptr, full_type_name);
83 }
84 
85 }  // namespace internal
86 }  // namespace protobuf
87 }  // namespace google
88