• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <jsonpb/jsonpb.h>
18 
19 #include <android-base/logging.h>
20 #include <google/protobuf/descriptor.h>
21 #include <google/protobuf/message.h>
22 #include <google/protobuf/util/json_util.h>
23 #include <google/protobuf/util/type_resolver_util.h>
24 
25 namespace android {
26 namespace jsonpb {
27 
28 using google::protobuf::DescriptorPool;
29 using google::protobuf::Message;
30 using google::protobuf::scoped_ptr;
31 using google::protobuf::util::NewTypeResolverForDescriptorPool;
32 using google::protobuf::util::TypeResolver;
33 
34 static constexpr char kTypeUrlPrefix[] = "type.googleapis.com";
35 
GetTypeUrl(const Message & message)36 std::string GetTypeUrl(const Message& message) {
37     return std::string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name();
38 }
39 
MessageToJsonString(const Message & message)40 ErrorOr<std::string> MessageToJsonString(const Message& message) {
41     scoped_ptr<TypeResolver> resolver(
42             NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool()));
43 
44     google::protobuf::util::JsonOptions options;
45     options.add_whitespace = true;
46 
47     std::string json;
48     auto status = BinaryToJsonString(resolver.get(), GetTypeUrl(message),
49                                      message.SerializeAsString(), &json, options);
50 
51     if (!status.ok()) {
52         return MakeError<std::string>(status.error_message().as_string());
53     }
54     return ErrorOr<std::string>(std::move(json));
55 }
56 
57 namespace internal {
JsonStringToMessage(const std::string & content,Message * message)58 ErrorOr<std::monostate> JsonStringToMessage(const std::string& content, Message* message) {
59     scoped_ptr<TypeResolver> resolver(
60             NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool()));
61 
62     std::string binary;
63     auto status = JsonToBinaryString(resolver.get(), GetTypeUrl(*message), content, &binary);
64     if (!status.ok()) {
65         return MakeError<std::monostate>(status.error_message().as_string());
66     }
67     if (!message->ParseFromString(binary)) {
68         return MakeError<std::monostate>("Fail to parse.");
69     }
70     return ErrorOr<std::monostate>();
71 }
72 }  // namespace internal
73 
74 }  // namespace jsonpb
75 }  // namespace android
76