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);

// Suppose you want to parse a message type with a specific type name.
const Descriptor* descriptor = pool.FindMessageTypeByName("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(message_type_to_parse);
>   DynamicMessageFactory factory;
>   unique_ptr<Message> message = factory.GetPrototype(descriptor)->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] 
> <javascript:>> 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] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <javascript:>.
>> 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.

Reply via email to