Skip to content

Instantly share code, notes, and snippets.

@RPG-18
Last active October 17, 2021 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RPG-18/761028780146793ee8035a3e56b279c1 to your computer and use it in GitHub Desktop.
Save RPG-18/761028780146793ee8035a3e56b279c1 to your computer and use it in GitHub Desktop.
Protobuf to json on C++
#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