0

Given the following dmp.proto file...

syntax = "proto3";

import "google/protobuf/any.proto";
import "google/protobuf/descriptor.proto";


message Engine1Specific {
    bool enabled = 1;
    double field1 = 2;
    double field2 = 3;
    double field3 = 4;
}

message EngineSpecific {
    string msg_name = 1;
    google.protobuf.FileDescriptorProto msg_proto = 2;
    google.protobuf.Any msg_content = 3;
}

message State {
    string basic_parameter = 1;
    EngineSpecific engine_specific = 2;
}

and the following C++ code...

    State state;
    state.set_basic_parameter("some basic value");
    
    Engine1Specific engine1Specific;
    engine1Specific.set_enabled(true);
    engine1Specific.set_field1(24.f);
    engine1Specific.set_field2(8000.f);
    engine1Specific.set_field3(12.f);

    auto specific(state.mutable_engine_specific());
    specific->set_msg_name("Engine1Specific");
    specific->mutable_msg_content()->PackFrom(engine1Specific);
    engine1Specific.GetDescriptor()->file()->CopyTo(specific->mutable_msg_proto());
    if (!specific->mutable_msg_proto()->has_name())
    {
        specific->mutable_msg_proto()->set_name("dmp.proto");
    }

    std::cout << "State: " << state.DebugString() << std::endl;

    google::protobuf::FileDescriptorProto const& fileDescriptorProto(state.engine_specific().msg_proto());
    google::protobuf::DescriptorPool descriptorPool;
    for (auto dependency : fileDescriptorProto.dependency())
    {
        std::cout << "Dependency: " << dependency << std::endl;
    }
    google::protobuf::FileDescriptor const * fileDescriptor(descriptorPool.BuildFile(fileDescriptorProto));

The call to BuildFile() is returning a null pointer with the following output to stdout

[libprotobuf ERROR protobuf\src\v3.19.4-3d4c96d55c.clean\src\google\protobuf\descriptor.cc:4202] Invalid proto descriptor for file "dmp.proto":
[libprotobuf ERROR protobuf\src\v3.19.4-3d4c96d55c.clean\src\google\protobuf\descriptor.cc:4205]   google/protobuf/any.proto: Import "google/protobuf/any.proto" has not been loaded.
[libprotobuf ERROR protobuf\src\v3.19.4-3d4c96d55c.clean\src\google\protobuf\descriptor.cc:4205]   google/protobuf/descriptor.proto: Import "google/protobuf/descriptor.proto" has not been loaded.
[libprotobuf ERROR protobuf\src\v3.19.4-3d4c96d55c.clean\src\google\protobuf\descriptor.cc:4205]   EngineSpecific.msg_proto: ".google.protobuf.FileDescriptorProto" is not defined.
[libprotobuf ERROR protobuf\src\v3.19.4-3d4c96d55c.clean\src\google\protobuf\descriptor.cc:4205]   EngineSpecific.msg_content: ".google.protobuf.Any" is not defined.

How do I make sure the dependencies are loaded for imports or is there something else I should be doing for BuildFile()?

  • You are trying to interpret your `FileDescriptorProto` in the context of an empty `DescriptorPool`, one that doesn't know anything about any other .proto files. So it fails to resolve dependencies (aka `import` directives). Try using `DesriptorPool::generated_pool()` instead - it's a pool of all descriptors compiled into your binary. – Igor Tandetnik Jul 22 '22 at 01:30
  • I realize my pool is empty. Are you suggesting that I call `BuildFile()` on the generated pool? `DescriptorPool::generated_pool()` returns a `const DescriptorPool *` and `DescriptorPool::BuildFile()` is a non-const method. I cannot call `BuildFile()` on the generated pool. – Michael Ngarimu Jul 22 '22 at 02:57

1 Answers1

0

The solution I found was to create my DescriptorPool using the generated pool as an underlay i.e.

google::protobuf::DescriptorPool descriptorPool(google::protobuf::DescriptorPool::generated_pool());