Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for cross-module proto definition parsing #3

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ bin
Debug
.cproject
.project
*.i*
erl_protobuf_test/.eunit/
erl_protobuf_test/deps/
erl_protobuf_test/ebin/
Expand Down
47 changes: 33 additions & 14 deletions src/ErlangGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,41 +139,46 @@ class ErlangGenerator : public CodeGenerator {
return out.str();
}

inline const string normalize_string(const string& orig) const
{
std::stringstream out;

for(string::const_iterator sI=orig.begin();sI != orig.end(); ++sI)
{
if(*sI == '.')
out << "_";
else
out << *sI;
}
return out.str();
}

inline const string file_basename(const string& filename) const {
return filename.substr(0,filename.find(".proto")).substr(filename.find_last_of('/')+1);
}

inline const string module_name(const FileDescriptor* file) const {
return to_atom(file_basename(file->name())+"_pb");
return to_atom(normalize_string(file->package().empty() ? "" : file->package() + "_") + file_basename(file->name()) + "_pb");
}

inline const std::string normalized_scope(const string& full_name, const string& package="") const
{
std::stringstream out;
string name;
if(!package.empty())
name=full_name.substr(package.size()+1);
else
name=full_name;
for(string::const_iterator sI=name.begin();sI != name.end(); ++sI)
{
if(*sI == '.')
out << "__";
else
out << *sI;
}
return out.str();
return normalize_string(name);
}

inline const std::string normalized_scope(const Descriptor* d) const
{
if(is_strict_naming)
return normalized_scope(d->full_name(),d->file()->package());
else
return normalized_scope(d->full_name(),d->file()->package());
return normalized_scope(d->full_name(),d->file()->package());
}


inline const string record_name(const Descriptor* message, const string& prefix="", const string& postfix="") const {
return to_atom(prefix
+ normalized_scope(message->full_name(),message->file()->package())
Expand All @@ -187,7 +192,11 @@ class ErlangGenerator : public CodeGenerator {
}

inline const string field_name(const FieldDescriptor* field) const {
return to_atom(field->name());
//TODO: Add checks for erlang keywords
if ("end" == field->name() || "begin" == field->name())
return to_atom(field->name() + string("_"));
else
return to_atom(field->name());
}

inline const string field_tag(const FieldDescriptor* field) const {
Expand Down Expand Up @@ -220,12 +229,22 @@ class ErlangGenerator : public CodeGenerator {
{
return to_atom(string("decode_") + normalized_scope(d)+"_impl");
}

inline const std::string decode_msg_name(const Descriptor* d) const
{
return to_atom(module_name(d->file()) + string(":") + decode_name(d));
}

inline const std::string encode_name(const Descriptor* d) const
{
return to_atom(string("encode_") + normalized_scope(d));
}

inline const std::string encode_msg(const Descriptor* d) const
{
return to_atom(module_name(d->file()) + string(":") + encode_name(d));
}

inline const std::string to_enum_name(const EnumDescriptor* d) const
{
return to_atom(string("to_") + normalized_scope(d->full_name(),d->file()->package()));
Expand Down
23 changes: 17 additions & 6 deletions src/ErlangSourceGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,18 @@ void ErlangGenerator::field_to_decode_function(Printer &out, const FieldDescript
break;
case FieldDescriptor::TYPE_MESSAGE:
// No such thing as a packed series of messages, so just append/replace multiple encounters.
vars["decode"]=decode_impl_name(field->message_type());
if (module_name(field->containing_type()->file()) == module_name(field->message_type()->file()))
vars["decode"]=decode_impl_name(field->message_type());
else
vars["decode"]=decode_msg_name(field->message_type());
if(field->is_repeated())
out.Print(vars,"($id$,{length_encoded,Bin},#$rec${$field$=F}=Rec) when is_list(F) -> Rec#$rec${$field$ = Rec#$rec$.$field$ ++ [$decode$(Bin)]}\n");
else
out.Print(vars,"($id$,{length_encoded,Bin},Rec) -> Rec#$rec${$field$ = $decode$(Bin)}");
break;
case FieldDescriptor::TYPE_ENUM:
// As with integer types, but the additional step of to_enum()
vars["to_enum"]=to_enum_name(field->enum_type());
vars["to_enum"]=module_name(field->file()) + string(":") + to_enum_name(field->enum_type());
if(field->is_repeated())
out.Print(vars,"($id$,{varint,Enum},#$rec${$field$=F}=Rec) when is_list(F) -> Rec#$rec${$field$=Rec#$rec$.$field$ ++ [$to_enum$(Enum)]}\n");
else
Expand Down Expand Up @@ -207,7 +210,7 @@ void ErlangGenerator::encode_decode_for_message(Printer& out, const Descriptor*

switch(field->type()) {
case FieldDescriptor::TYPE_ENUM:
vars["from_enum"]=from_enum_name(field->enum_type());
vars["from_enum"]=module_name(field->file()) + string(":") + from_enum_name(field->enum_type());
if(field->is_repeated())
{
out.Print(vars," [protocol_buffers:encode($id$,int32,$from_enum$(X)) || X <- R#$rec$.$field$]");
Expand All @@ -216,7 +219,11 @@ void ErlangGenerator::encode_decode_for_message(Printer& out, const Descriptor*
}
break;
case FieldDescriptor::TYPE_MESSAGE:
vars["encode"]=encode_name(field->message_type());
if (module_name(field->containing_type()->file()) == module_name(field->message_type()->file()))
vars["encode"]=encode_name(field->message_type());
else
vars["encode"]=encode_msg(field->message_type());

if(field->is_repeated())
out.Print(vars," [ protocol_buffers:encode($id$,length_encoded,$encode$(X)) || X <- R#$rec$.$field$]");
else
Expand All @@ -242,8 +249,12 @@ void ErlangGenerator::encode_decode_for_message(Printer& out, const Descriptor*

void ErlangGenerator::generate_source(Printer& out, const FileDescriptor* file) const
{
out.Print("-module($module$).\n"
"-include(\"$module$.hrl\").\n\n"
out.Print("-module($module$).\n", "module", module_name(file));
for(int i=0; i < file->dependency_count();++i) {
out.Print("-include(\"$module$.hrl\").\n", "module", module_name(file->dependency(i)));
}
out.Print("\n");
out.Print("-include(\"$module$.hrl\").\n\n"
"-export([\n"
,"module",module_name(file));
for(int i=0; i < file->enum_type_count();++i)
Expand Down