64 google::protobuf::Message* proto,
67 std::string uncompressed;
69 VLOG(1) <<
"ReadFileToProto(): input is gzipped";
82 constexpr double kMaxBinaryProtoParseShrinkFactor = 2;
83 std::string binary_format_error;
84 if (proto->ParsePartialFromString(data) &&
85 (allow_partial || proto->IsInitialized())) {
91 proto->DiscardUnknownFields();
92 if (proto->ByteSizeLong() <
93 data.size() / kMaxBinaryProtoParseShrinkFactor) {
95 "The input may be a binary protobuf payload, but it"
96 " probably is from a different proto class";
98 VLOG(1) <<
"StringToProto(): input seems to be a binary proto";
99 return absl::OkStatus();
103 struct :
public google::protobuf::io::ErrorCollector {
104 void RecordError(
int line, google::protobuf::io::ColumnNumber column,
105 absl::string_view error_message)
override {
106 if (!message.empty()) message +=
", ";
107 absl::StrAppendFormat(&message,
"%d:%d: %s",
109 line + 1, column, error_message);
113 google::protobuf::TextFormat::Parser text_parser;
114 text_parser.RecordErrorsTo(&text_format_error);
115 text_parser.AllowPartialMessage(allow_partial);
116 if (text_parser.ParseFromString(data, proto)) {
117 VLOG(1) <<
"StringToProto(): input is a text proto";
118 return absl::OkStatus();
120 std::string json_error;
121 absl::Status json_status =
122 JsonStringToMessage(data, proto, JsonParseOptions());
123 if (json_status.ok()) {
128 constexpr int kMaxJsonToBinaryShrinkFactor = 30;
129 if (proto->ByteSizeLong() < data.size() / kMaxJsonToBinaryShrinkFactor) {
130 json_status = absl::InvalidArgumentError(
131 "The input looks like valid JSON, but probably not"
132 " of the right proto class");
134 VLOG(1) <<
"StringToProto(): input is a proto JSON";
135 return absl::OkStatus();
138 return absl::InvalidArgumentError(absl::StrFormat(
139 "binary format error: '%s', text format error: '%s', json error: '%s'",
140 binary_format_error, text_format_error.message, json_status.message()));
144 const google::protobuf::Message& proto,
146 bool append_extension_to_file_name) {
147 std::string file_type_suffix;
148 std::string output_string;
149 google::protobuf::io::StringOutputStream stream(&output_string);
150 auto make_error = [filename](absl::string_view error_message) {
151 return absl::InternalError(absl::StrFormat(
152 "WriteProtoToFile('%s') failed: %s", filename, error_message));
154 switch (proto_write_format) {
156 if (!proto.SerializeToZeroCopyStream(&stream)) {
157 return make_error(
"SerializeToZeroCopyStream()");
159 file_type_suffix =
".bin";
162 if (!google::protobuf::TextFormat::PrintToString(proto, &output_string)) {
163 return make_error(
"TextFormat::PrintToString()");
167 google::protobuf::util::JsonPrintOptions options;
168 options.add_whitespace =
true;
169#if PROTOBUF_VERSION >= 5026000
170 options.always_print_fields_with_no_presence =
true;
172 options.always_print_primitive_fields =
true;
174 options.preserve_proto_field_names =
true;
175 if (!google::protobuf::util::MessageToJsonString(proto, &output_string,
178 LOG(WARNING) <<
"Printing to stream failed.";
179 return make_error(
"google::protobuf::util::MessageToJsonString()");
181 file_type_suffix =
".json";
185 google::protobuf::util::JsonPrintOptions options;
186 options.add_whitespace =
true;
187 if (!google::protobuf::util::MessageToJsonString(proto, &output_string,
190 LOG(WARNING) <<
"Printing to stream failed.";
191 return make_error(
"google::protobuf::util::MessageToJsonString()");
193 file_type_suffix =
".json";
197 std::string gzip_string;
199 output_string.swap(gzip_string);
200 file_type_suffix +=
".gz";
202 std::string output_filename(filename);
203 if (append_extension_to_file_name) output_filename += file_type_suffix;
204 VLOG(1) <<
"Writing " << output_string.size() <<
" bytes to '"
205 << 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)