1

i am new in protobuf . i want practice an simple example for me with description in protobuf. I have a .proto file in which a message is defined. Now, using the descriptor, I want to read and display the entire part of this file line by line. but get error

this is my .proto file::

syntax = "proto3";

package PERSON;

message Person {

     string name = 1;
     int32 age = 2;
}

this is my main code::

#include <QCoreApplication>
#include <QDebug>
#include <iostream>
#include <fstream>



#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>



int main() {

const std::string file_name = "/home/hossein/QtProject/test/person.pb.h";

    // Read the file into a string
    std::ifstream input(file_name, std::ios::binary);
    //    std::ifstream input("person.bin", std::ios::binary);
    std::string file_contents((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());

    // Create a DescriptorPool and parse the file
    google::protobuf::DescriptorPool descriptor_pool;
    google::protobuf::FileDescriptorProto file_descriptor_proto;


    google::protobuf::io::ArrayInputStream input_stream(file_contents.data(), file_contents.size());
    std::cerr << file_contents.size() << " sizeeeee" << std::endl;
    std::cerr << file_contents.data() << std::endl;

    if (!google::protobuf::TextFormat::Parse(&input_stream, &file_descriptor_proto)) {
        std::cerr << "Failed to parse " << file_name << std::endl;
        return 1;
    }




    const google::protobuf::FileDescriptor* file_descriptor = descriptor_pool.BuildFile(file_descriptor_proto);
    if (file_descriptor == nullptr) {
        std::cerr << "Failed to build file descriptor for " << file_name << std::endl;
        return 1;
    }

    // Print the message types and fields defined in the file
    std::cout << "File " << file_name << " defines the following message types:" << std::endl;
    for (int i = 0; i < file_descriptor->message_type_count(); i++) {
        const google::protobuf::Descriptor* message_descriptor = file_descriptor->message_type(i);
        std::cout << "  Message type: " << message_descriptor->full_name() << std::endl;
        std::cout << "  Fields:" << std::endl;
        for (int j = 0; j < message_descriptor->field_count(); j++) {
            const google::protobuf::FieldDescriptor* field_descriptor = message_descriptor->field(j);
            std::cout << "    Field name: " << field_descriptor->name() << std::endl;
            std::cout << "    Field type: " << field_descriptor->type_name() << std::endl;
        }
    }

   
    return 0;
}

and get this error :::

[libprotobuf ERROR google/protobuf/text_format.cc:322] Error parsing text-format google.protobuf.FileDescriptorProto: 2:8: Expected ":", found "=".
Failed to parse /home/hossein/QtProject/test/person.proto

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
hossein
  • 13
  • 3

1 Answers1

0

the "text format" in protobuf is a bespoke human readable format for data payloads that is similar to JSON (but is not JSON); it is not the same as the .proto schema language; to quote from https://protobuf.dev/reference/protobuf/textformat-spec/ (emphasis mine):

The protocol buffer Text Format Language specifies a syntax for representation of protobuf data in text form, which is often useful for configurations or tests.

This format is distinct from the format of text within a .proto schema, for example.

You cannot use the protobuf runtime to parse schema definitions in this way. If there is a schema parser API: it isn't that.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I am not profissional in protobuf descriptor , please provide me a example for solving this problem And Can I write my .proto like json file ? and If it is possible could tell me is there any method in google protobuf library or not? @MarcGravell – hossein Jul 05 '23 at 17:17
  • Protobuf simply isn't designed to be loaded at runtime, you need to use the compiler to generate the runtime code – Alan Birtles Jul 06 '23 at 06:32
  • can i use reflectionApi for read data without generate .proto file???@AlanBirtles – hossein Jul 06 '23 at 07:11
  • @hossein You can, but it doesn't use the proto file: https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/ – Alan Birtles Jul 06 '23 at 07:19
  • you say that there is no way to read .proto file and parse it without genearte it???@AlanBirtles – hossein Jul 06 '23 at 07:28
  • @hossein I'm saying that isn't what `protobuf::TextFormat::Parse` does; I don't know if an API to parse .proto exists in the Google libraries - I *do* know that one exists in protobuf-net (for C# etc), but: that isn't going to help you here; typically, folks use `protoc` to work with .proto files; one option is to use `protoc --descriptor_set_out` on the input, which produces a binary output with payload matching `descriptor.proto` (readily available), which you can load using the protobuf binary deserialize API – Marc Gravell Jul 06 '23 at 15:24