On Tue, Sep 9, 2014 at 11:03 PM, Jan Kyjovský <[email protected]> wrote:
> Variable proto contains some information about structure although > proto.name is blank (don't know why). > You need to set the proto.name yourself: https://github.com/google/protobuf/blob/master/src/google/protobuf/compiler/importer.cc#L147 I guess this is the reason why it doesn't work. Sorry that I missed this in my code example. > BuildFile returns NULL as well as FindMessageTypeByName. Whey I went > deeper in debugging I noticed that BuildFile is trying to look up for that > file I provide in its tables but these are empty as well. > > On Tuesday, 9 September 2014 22:35:05 UTC+2, Feng Xiao wrote: > >> >> >> On Mon, Sep 8, 2014 at 10:32 PM, Jan Kyjovský <[email protected]> >> wrote: >> >>> Hi, >>> >>> sorry for delay. I've been experimenting with that eve since I could >>> return to this issue. Mostly about composition of project since whenever I >>> try separate your sources from projects and use them individually I§ve been >>> getting tons of errors (linking one included). In the end I get along with >>> static library linked in my project. But putting that aside. >>> >>> I haven't get as far as to use all your example. I am stuck and fact >>> that when asking pool for specific message I am getting empty default >>> descriptor as result. I am attaching my code so far could you please advise >>> where I am making mistake? >>> >>> Its just short program where I was trying to figure out how to use it. >>> >>> #include <io.h> >>> #include <fcntl.h> >>> #include <stdio.h> >>> #include <string> >>> #include <vector> >>> #include "descriptor.h" >>> #include "descriptor.pb.h" >>> #include "zero_copy_stream_impl.h" >>> #include "tokenizer.h" >>> #include "parser.h" >>> #include "substitute.h" >>> #include "dynamic_message.h" >>> >>> using namespace google::protobuf; >>> >>> class ParserErrorCollector : public io::ErrorCollector >>> { >>> public: >>> ParserErrorCollector() {} >>> ~ParserErrorCollector() {} >>> >>> std::string text_; >>> >>> // implements ErrorCollector ------------------------------------- >>> void AddError(int line, int column, const std::string& message) >>> { >>> strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + >>> 1, message); >>> } >>> >>> void AddWarning(int line, int column, const std::string& message) >>> { >>> AddError(line, column, "WARNING:" + message); >>> } >>> }; >>> >>> bool ParseProtoFile(std::string strFileName, FileDescriptorProto* >>> result); >>> >>> void main() >>> { >>> std::string strFile = "C:\\Users\\kyjovjan\\Desktop\ >>> \ProtoExperiment\\addressbook.proto"; >>> >>> // Build the descriptor pool >>> DescriptorPool pool; >>> >>> FileDescriptorProto proto; >>> ParseProtoFile(strFile, &proto); >>> >> pool.BuildFile(proto); >>> >> Have you checked the return value of these two method calls? >> >> >>> >>> // Suppose you want to parse a message type with a specific type name. >>> const Descriptor* descriptor = pool.FindMessageTypeByName(" >>> AddressBook"); >>> >> Does this return NULL or non-NULL? If it's the later, it means you have >> successfully constructed the descriptor for AddressBook. >> >> >>> DynamicMessageFactory factory; >>> Message *message = factory.GetPrototype(descriptor)->New(); >>> } >>> >>> // Convert .proto files into parsed FileDescriptorProto >>> bool ParseProtoFile(std::string strFileName, FileDescriptorProto* result) >>> { >>> int file_descriptor = open(strFileName.c_str(), O_RDONLY); >>> >>> ParserErrorCollector errCollector; >>> >>> io::FileInputStream stream(file_descriptor); >>> stream.SetCloseOnDelete(true); >>> io::Tokenizer tokenizer(&stream, &errCollector); >>> compiler::Parser parser; >>> >>> return parser.Parse(&tokenizer, result); >>> >>> return true; >>> } >>> >>> >>> On Tuesday, 12 August 2014 19:36:13 UTC+2, Feng Xiao wrote: >>>> >>>> Protobuf supports creating message types dynamically at runtime and use >>>> them for parsing/serialization/etc. >>>> >>>> First you need to build up a DescriptorPool >>>> <https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.h#1141> >>>> that contains all types that you may want to use. There are two approaches >>>> to construct this pool. One is to call DescriptorPool::BuildFile() directly >>>> with parsed proto files. For example: >>>> // Convert .proto files into parsed FileDescriptorProto >>>> bool ParseProtoFile(string filename, FileDescriptorProto* result) { >>>> FileInputStream stream(filename); >>>> google::protobuf::io::Tokenizer tokenizer(&stream); >>>> google::protobuf::compiler::Parser parser; >>>> return parser.Parse(&tokenizer, result); >>>> } >>>> // Build the descriptor pool >>>> DescriptorPool pool; >>>> for (string filename : proto_files) { >>>> FileDescriptorProto proto; >>>> ParseProtoFile(filename, &proto); >>>> pool.BuildFile(proto); >>>> } >>>> >>>> After you have the pool, you can query for a type by its name. For >>>> example, DescriptorPool::FindMessageTypeByName(). >>>> >>>> Then to actually parse/serialize/use message types in the pool, you >>>> need to construct message objects around them. DynamicMessage >>>> <https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/dynamic_message.h#53> >>>> is used for that: >>>> // Suppose you want to parse a message type with a specific type name. >>>> Descriptor* descriptor = pool.FindMessageTypeByName(mes >>>> sage_type_to_parse); >>>> DynamicMessageFactory factory; >>>> unique_ptr<Message> message = factory.GetPrototype(descripto >>>> r)->New(); >>>> // Use the message object for parsing/etc. >>>> message->ParseFromString(input_data); >>>> // Access a specific field in the message >>>> FieldDescriptor* field = descriptor->FindFieldByName(field_to_read); >>>> switch (field->type()) { >>>> case TYPE_INT32: message->GetReflection()->GetInt32(*message, >>>> field); break; >>>> ... >>>> } >>>> >>>> On Mon, Aug 11, 2014 at 9:31 PM, Jan Kyjovský <[email protected]> >>>> wrote: >>>> >>>>> Hi, >>>>> >>>>> I have very specific problem. I have data and proto file available and >>>>> my application should take both and based on external configuration >>>>> determine how to interpret data (many different types/messages in proto). >>>>> Yet that can be determine only during run. My question is if there is any >>>>> support for that, I mean that I will be able to parse proto and decode >>>>> data >>>>> based on content of interpret intermediate structures. >>>>> >>>>> I have been trying to analyze this possibility directly from codes but >>>>> not with much success. I would be glad for any guidance. >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Protocol Buffers" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> Visit this group at http://groups.google.com/group/protobuf. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Protocol Buffers" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/protobuf. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- > You received this message because you are subscribed to the Google Groups > "Protocol Buffers" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/protobuf. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Protocol Buffers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/protobuf. For more options, visit https://groups.google.com/d/optout.
