I have remade code so I now add into descriptor database all protofiles
specified by directory. There is but little problem with error handling.
>From nature how I am handling errors it seems that message is possible to
decode but there is one error in error collector which is bothering me:
1:1: ERROR: Multiple package definitions.
*My protos are defined as follows:*
*addressbook_fragmented.proto:*
import "phone.proto";
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2; // Unique ID number for this person.
optional string email = 3;
// enum PhoneType {
// MOBILE = 0;
// HOME = 1;
// WORK = 2;
// }
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
optional int32 age = 5;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
*phone.proto:*
package tutorial;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
Even though there is error in error collector I can ignore it and decode
message successfully. Yet if I try to remove this package info from
phone.proto itis not detecting any error but FindMessageTypeByName fails to
find data type. I am suspecting since not all references for person data
type I am asking for are resolved it fails.
So I am confused how exactly should be these package keywords be used?
On Wednesday, 3 June 2015 19:05:59 UTC+2, Feng Xiao wrote:
>
>
>
> On Wed, Jun 3, 2015 at 12:40 AM, Jan Kyjovský <[email protected]
> <javascript:>> wrote:
>
>> HI,
>>
>> I somehow understand what you mean but still I lack in experience with
>> it. I tried to switch to descriptor database but still I got some problems.
>>
>> C_ProtoDecoder::C_ProtoDecoder(std::string strFile)
>> {
>> m_strProtoFile = strFile;
>>
>> // Build the descriptor pool
>> m_bConstructed = ParseProtoFile(&m_ProtoFileDescr);
>>
>> if (m_bConstructed)
>> {
>> m_ProtoDescrDatabase.Add(m_ProtoFileDescr);
>> m_Pool = new DescriptorPool(&m_ProtoDescrDatabase);
>> }
>> }
>>
>> C_ProtoDecoder::~C_ProtoDecoder()
>> {
>> delete m_Pool;
>> }
>>
>> bool C_ProtoDecoder::DecodeDataAsTypeFromWireFormat(std::string
>> strWireFormat, std::string strType)
>> {
>> Descriptor *descriptor = (Descriptor
>> *)m_Pool->FindMessageTypeByName(strType);
>> Message *message = m_MessageFactory.GetPrototype(descriptor)->New();
>>
>> if (descriptor == NULL)
>> {
>> char szError[256];
>>
>> sprintf(szError, "Unknown data type %s!", strType.c_str());
>> m_InternalPrinter.AddErrorMessage(szError);
>>
>> return false;
>> }
>>
>> bool bFlag = message->ParseFromString(strWireFormat);
>>
>> if (!bFlag)
>> {
>> m_InternalPrinter.AddErrorMessage("Encoding error!");
>> }
>> else
>> {
>> m_Transformator.MorphToStructs(*message);
>> }
>>
>> return true;
>> }
>>
>> bool C_ProtoDecoder::ParseProtoFile(FileDescriptorProto *result)
>> {
>> int file_descriptor = open(m_strProtoFile.c_str(), O_RDONLY);
>>
>> if (file_descriptor == -1)
>> {
>> char szError[256];
>>
>> sprintf(szError, "Invalid proto file \"%s\"!",
>> m_strProtoFile.c_str());
>> m_InternalPrinter.AddErrorMessage(szError);
>>
>> return false;
>> }
>>
>> C_ParserErrorCollector errCollector;
>>
>> io::FileInputStream stream(file_descriptor);
>> stream.SetCloseOnDelete(true);
>> io::Tokenizer tokenizer(&stream, &errCollector);
>> result->set_name(m_strProtoFile);
>>
>> compiler::Parser parser;
>>
>> return parser.Parse(&tokenizer, result);
>> }
>>
>> I have used SimpleDescriptorDatabase since it looked like it has already
>> implemented and its covering what I will be requiring from it (or at least
>> I think it does)
>>
> If you use SimpleDescriptorDatabase, you need to add all .proto files into
> the database explicitly. For example, if you have 2 .proto files foo.proto
> and bar.proto, where bar.proto imports foo.proto, you need to add both
> foo.proto and bar.proto to SimpleDescriptorDatabase. If you already have a
> list of all proto files, using SimpleDescriptorDatabase should be fine.
>
>
>>
>> Everything is fine until I try to get descriptor by FindMessageTypeByName
>> from pool. It returns null. Am I committing some steps?
>>
> I don't see anything obviously wrong in your code.
>
>
>
>
>>
>>
>> On Tuesday, 2 June 2015 19:49:53 UTC+2, Feng Xiao wrote:
>>>
>>>
>>>
>>> On Mon, Jun 1, 2015 at 9:55 PM, Jan Kyjovský <[email protected]>
>>> wrote:
>>>
>>>> Hi again,
>>>>
>>>> As I have stated before I am done with decoding, but now I am solving
>>>> different type of problem. As I have mentioned before imports may prove
>>>> problematic to our implementation.
>>>>
>>>> Let me describe use-case how it will be used. There will be
>>>> configuration stating for which data (message number, specific field) will
>>>> be applied which proto file and structure (data type). Therefore there is
>>>> no knowledge about other proto files up until now. In run time data are
>>>> fetched and shipped to decoder. In current implementation is specified
>>>> proto file loaded and specific type used for decoding. That much is clear
>>>> and works. But if some parts of structures are imported. It will fail.
>>>> That
>>>> much is clear that using just one file descriptor will be not enough as
>>>> you
>>>> have mentioned earlier.
>>>>
>>>> That leads to your proposition (posted earlier) to use
>>>> DescriptorDatabase. I have looked on implementation of classes derived
>>>> from
>>>> DscriptorDatabase. I am more or less able to provide directory for
>>>> SourceTree, but that doesn't answer question about import. I mean since I
>>>> am aware of only one proto file. Is import done automatically or other
>>>> files has to be also included manually into database?
>>>>
>>>
>>>> Another question I have is bout order of operations. You mentioned that
>>>> I have to first call FindFileByName() before
>>>> callingFindMessageTypeByName(). That may be problem since I am not aware
>>>> in
>>>> which proto file may be located.
>>>>
>>>> Also I have noticed in code note that proto files with types used in
>>>> other proto files have to be "loaded" first. So is there any way how to
>>>> ensure right order of loading?
>>>>
>>> Most of the work is done by DescriptorPool. Basically when you call
>>> FindFileByName() on a .proto file that is not yet loaded into the pool,
>>> DescriptorPool will call FindFileByName() on its underlying
>>> DescriptorDatabase to get the FileDescriptorProto for file. Then
>>> DescriptorPool will check the imports of this FileDescriptorPool. If it
>>> finds unsatisfied imports (i.e., files imported but not yet in the pool),
>>> it will issue FindFileByName() to the DescriptorDatabase again for these
>>> files.
>>>
>>> So basically DescriptorDatabase only needs to know how to load a single
>>> .proto file, while DescriptorPool will take care of the imports and
>>> ordering.
>>>
>>> Depending on what DescriptorDatabase you are using, you may or may not
>>> need to call FindFileByName() first. If the DescriptorDatabase has
>>> implement FindFileContainingSymbol, then calling
>>> DescriptorPool::FindMessageTypeByName() directly will be able to find the
>>> file using this method. If not (the case with
>>> SourceTreeDescriptorDatabase), FindFileByName() must be called first. As
>>> DescriptorPool will be able to find imports by itself, you don't need to
>>> call FindFileByName() for every file, but just the file that you actually
>>> need to use.
>>>
>>>
>>>>
>>>> I hope my question are not too strange but I my knowledge about google
>>>> protocol buffers are a bit limited.
>>>>
>>>> --
>>>> 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] <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.