| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_ |
| |
| #include <cstdint> |
| #include <filesystem> // NOLINT |
| #include <fstream> |
| #include <iostream> |
| #include <sstream> |
| #include <string> |
| #include <system_error> // NOLINT |
| |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "absl/strings/string_view.h" |
| #include "google/protobuf/message.h" |
| #include "google/protobuf/text_format.h" |
| |
| namespace deterministic_bmc { |
| |
| enum ProtoFormat : uint8_t { |
| kTextProto, |
| kBinaryProto, |
| }; |
| |
| inline std::ostream& operator<<(std::ostream& os, ProtoFormat format) { |
| switch (format) { |
| case ProtoFormat::kTextProto: |
| return os << "TextProto"; |
| case ProtoFormat::kBinaryProto: |
| return os << "BinaryProto"; |
| default: |
| return os << "Invalid ProtoFormat"; |
| } |
| } |
| |
| template <typename T> |
| class ProtoReader { |
| public: |
| // Reads a proto from a file. |
| // |
| // path: The path to the file. |
| // format: The format of the proto. |
| // |
| // Returns a proto if successful, or an error if unsuccessful. |
| static absl::StatusOr<T> ReadProtoFromFile(absl::string_view path, |
| ProtoFormat format); |
| }; |
| |
| template <typename T> |
| absl::StatusOr<T> ProtoReader<T>::ReadProtoFromFile(absl::string_view path, |
| ProtoFormat format) { |
| std::error_code ec; |
| if (!std::filesystem::exists(path, ec)) { |
| LOG(WARNING) |
| << "Proto file " << path |
| << " does not exist or filesystem::exists() failed with error: " |
| << (ec ? "N/A" : ec.message()); |
| return absl::NotFoundError( |
| absl::StrCat("ProtoReader: File not found: ", path)); |
| } |
| std::ifstream input(std::string(path), format == ProtoFormat::kBinaryProto |
| ? std::ios::in | std::ios::binary |
| : std::ios::in); |
| if (!input.is_open()) { |
| LOG(WARNING) << "Error opening file: " << path; |
| return absl::InternalError( |
| absl::StrCat("ProtoReader: Failed to open file: ", path)); |
| } |
| |
| // Read the entire file into a stringstream |
| std::stringstream buffer; |
| buffer << input.rdbuf(); |
| input.close(); |
| |
| T config; |
| // Parse the proto from the string |
| const std::string format_str = |
| (format == ProtoFormat::kBinaryProto) ? "binary" : "text"; |
| |
| if (format == ProtoFormat::kBinaryProto |
| ? !config.ParseFromString(buffer.str()) |
| : !::google::protobuf::TextFormat::ParseFromString(buffer.str(), &config)) { |
| LOG(WARNING) << "Error parsing " << format_str |
| << " proto from file: " << path; |
| return absl::InternalError(absl::StrCat("ProtoReader: Failed to parse ", |
| format_str, |
| " proto from file: ", path)); |
| } |
| |
| return config; |
| } |
| |
| } // namespace deterministic_bmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_ |