63 google::protobuf::Message*
proto,
66 std::string uncompressed;
68 VLOG(1) <<
"ReadFileToProto(): input is gzipped";
81 constexpr double kMaxBinaryProtoParseShrinkFactor = 2;
82 std::string binary_format_error;
83 if (
proto->ParsePartialFromString(data) &&
84 (allow_partial ||
proto->IsInitialized())) {
90 proto->DiscardUnknownFields();
91 if (
proto->ByteSizeLong() <
92 data.size() / kMaxBinaryProtoParseShrinkFactor) {
94 "The input may be a binary protobuf payload, but it"
95 " probably is from a different proto class";
97 VLOG(1) <<
"StringToProto(): input seems to be a binary proto";
98 return absl::OkStatus();
102 struct :
public google::protobuf::io::ErrorCollector {
103 void RecordError(
int line, google::protobuf::io::ColumnNumber
column,
104 absl::string_view error_message)
override {
106 absl::StrAppendFormat(&
message,
"%d:%d: %s",
112 google::protobuf::TextFormat::Parser text_parser;
113 text_parser.RecordErrorsTo(&text_format_error);
114 text_parser.AllowPartialMessage(allow_partial);
115 if (text_parser.ParseFromString(data,
proto)) {
116 VLOG(1) <<
"StringToProto(): input is a text proto";
117 return absl::OkStatus();
119 std::string json_error;
120 absl::Status json_status =
121 JsonStringToMessage(data,
proto, JsonParseOptions());
122 if (json_status.ok()) {
127 constexpr int kMaxJsonToBinaryShrinkFactor = 30;
128 if (
proto->ByteSizeLong() < data.size() / kMaxJsonToBinaryShrinkFactor) {
129 json_status = absl::InvalidArgumentError(
130 "The input looks like valid JSON, but probably not"
131 " of the right proto class");
133 VLOG(1) <<
"StringToProto(): input is a proto JSON";
134 return absl::OkStatus();
137 return absl::InvalidArgumentError(absl::StrFormat(
138 "binary format error: '%s', text format error: '%s', json error: '%s'",
139 binary_format_error, text_format_error.message, json_status.message()));
143 const google::protobuf::Message&
proto,
145 bool append_extension_to_file_name) {
146 std::string file_type_suffix;
147 std::string output_string;
148 google::protobuf::io::StringOutputStream stream(&output_string);
149 auto make_error = [filename](absl::string_view error_message) {
150 return absl::InternalError(absl::StrFormat(
151 "WriteProtoToFile('%s') failed: %s", filename, error_message));
153 switch (proto_write_format) {
155 if (!
proto.SerializeToZeroCopyStream(&stream)) {
156 return make_error(
"SerializeToZeroCopyStream()");
158 file_type_suffix =
".bin";
161 if (!google::protobuf::TextFormat::PrintToString(
proto, &output_string)) {
162 return make_error(
"TextFormat::PrintToString()");
166 google::protobuf::util::JsonPrintOptions options;
167 options.add_whitespace =
true;
168 options.always_print_fields_with_no_presence =
true;
169 options.preserve_proto_field_names =
true;
170 if (!google::protobuf::util::MessageToJsonString(
proto, &output_string,
173 LOG(WARNING) <<
"Printing to stream failed.";
174 return make_error(
"google::protobuf::util::MessageToJsonString()");
176 file_type_suffix =
".json";
180 google::protobuf::util::JsonPrintOptions options;
181 options.add_whitespace =
true;
182 if (!google::protobuf::util::MessageToJsonString(
proto, &output_string,
185 LOG(WARNING) <<
"Printing to stream failed.";
186 return make_error(
"google::protobuf::util::MessageToJsonString()");
188 file_type_suffix =
".json";
192 std::string gzip_string;
194 output_string.swap(gzip_string);
195 file_type_suffix +=
".gz";
197 std::string output_filename(filename);
198 if (append_extension_to_file_name) output_filename += file_type_suffix;
199 VLOG(1) <<
"Writing " << output_string.size() <<
" bytes to '"
200 << output_filename <<
"'";
absl::Status StringToProto(absl::string_view data, google::protobuf::Message *proto, bool allow_partial)
Exactly like ReadFileToProto(), but directly from the contents.
absl::Status WriteProtoToFile(absl::string_view filename, const google::protobuf::Message &proto, ProtoWriteFormat proto_write_format, bool gzipped, bool append_extension_to_file_name)