Last active
October 17, 2021 15:36
-
-
Save RPG-18/761028780146793ee8035a3e56b279c1 to your computer and use it in GitHub Desktop.
Protobuf to json on C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <google/protobuf/compiler/importer.h> | |
#include <google/protobuf/descriptor.h> | |
#include <google/protobuf/descriptor_database.h> | |
#include <google/protobuf/dynamic_message.h> | |
#include <google/protobuf/util/json_util.h> | |
#include <fstream> | |
#include <iostream> | |
using namespace google::protobuf; | |
using namespace google::protobuf::io; | |
using namespace google::protobuf::compiler; | |
using namespace google::protobuf::util; | |
class ConsoleErrorCollector final : public MultiFileErrorCollector { | |
public: | |
virtual void AddError(const std::string& filename, int line, int column, | |
const std::string& message) | |
{ | |
std::cerr << "File: "<<filename<<", Line:" << line << ", Column: " << column << ", Message:" << message << std::endl; | |
} | |
virtual void AddWarning(int line, ColumnNumber column, | |
const std::string &message) { | |
std::cerr << "Line: " << line << ", Column: " << column << ", Message:" << message << std::endl; | |
} | |
}; | |
std::string readMsg(); | |
int main() { | |
std::vector<DescriptorDatabase *> sources; | |
std::unique_ptr<MergedDescriptorDatabase> descriptor_set_in_database = std::make_unique<MergedDescriptorDatabase>(sources); | |
std::unique_ptr<MultiFileErrorCollector> error_collector = std::make_unique<ConsoleErrorCollector>(); | |
std::unique_ptr<DiskSourceTree> disk_source_tree = std::make_unique<DiskSourceTree>(); | |
disk_source_tree->MapPath("", "/home/dmitry/CLionProjects/protobuf/src"); | |
disk_source_tree->MapPath("", "/home/dmitry/CLionProjects/proto2json/proto_test"); | |
std::unique_ptr<SourceTreeDescriptorDatabase> source_tree_database = std::make_unique<SourceTreeDescriptorDatabase>(disk_source_tree.get(), descriptor_set_in_database.get()); | |
source_tree_database->RecordErrorsTo(error_collector.get()); | |
std::unique_ptr<DescriptorPool> descriptor_pool = std::make_unique<DescriptorPool>(source_tree_database.get(), | |
source_tree_database->GetValidationErrorCollector()); | |
descriptor_pool->EnforceWeakDependencies(true); | |
const FileDescriptor* parsed_file = | |
descriptor_pool->FindFileByName("order_enrichment.proto"); | |
if (parsed_file == nullptr) { | |
std::cerr<<"failed find&parse order_enrichment.proto"<<std::endl; | |
return 0; | |
} | |
std::cerr<<"Messages:"<<std::endl; | |
for (int i=0; i<parsed_file->message_type_count(); i++) { | |
std::cerr<<" "<<parsed_file->package()<<"."<<parsed_file->message_type(i)->name()<<std::endl; | |
}; | |
const Descriptor* type = descriptor_pool->FindMessageTypeByName("order_enrichment.EventOrderEnrichment"); | |
if (type == nullptr) { | |
std::cerr<<"failed find order_enrichment.EventOrderEnrichment"<<std::endl; | |
return 0; | |
} | |
DynamicMessageFactory dynamic_factory(descriptor_pool.get()); | |
std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New()); | |
auto msg = readMsg(); | |
bool parsed = message->ParseFromArray(msg.data(), msg.size()); | |
if (!parsed) { | |
std::cerr<<"failed parse message"<<std::endl; | |
} | |
std::string json; | |
JsonPrintOptions opt; | |
opt.add_whitespace = true; | |
MessageToJsonString(*message.get(), &json, opt); | |
std::cerr<<json<<std::endl; | |
return 0; | |
} | |
std::string readMsg() { | |
std::ifstream istrm("/home/dmitry/CLionProjects/proto2json/proto_test/msg", std::ios::binary); | |
if (!istrm.is_open()) { | |
std::cerr<<"filed open message file"<<std::endl; | |
return {}; | |
} | |
std::string res; | |
res.assign(281, 0); | |
istrm.read(&res[0], 281); | |
istrm.close(); | |
return res; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment