Skip to content

Commit 94680f5

Browse files
author
Wouter van Oortmerssen
committed
Added support for imports and many other .proto features.
Change-Id: I6600021b7ec8c486794349511232c3e604421c5b Tested: on Linux.
1 parent b4db888 commit 94680f5

File tree

15 files changed

+502
-203
lines changed

15 files changed

+502
-203
lines changed

docs/html/md__compiler.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
<li><code>--gen-mutable</code> : Generate additional non-const accessors for mutating FlatBuffers in-place.</li>
8585
<li><code>--gen-onefile</code> : Generate single output file (useful for C#)</li>
8686
<li><code>--raw-binary</code> : Allow binaries without a file_indentifier to be read. This may crash flatc given a mismatched schema.</li>
87-
<li><code>--proto</code>: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: <code>package</code>, <code>message</code>, <code>enum</code>, nested declarations. Does not support, but will skip without error: <code>import</code>, <code>option</code>. Does not support, will generate error: <code>service</code>, <code>extend</code>, <code>extensions</code>, <code>oneof</code>, <code>group</code>, custom options.</li>
87+
<li><code>--proto</code>: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: <code>package</code>, <code>message</code>, <code>enum</code>, nested declarations, <code>import</code> (use <code>-I</code> for paths), <code>extend</code>, <code>oneof</code>, <code>group</code>. Does not support, but will skip without error: <code>option</code>, <code>service</code>, <code>extensions</code>, and most everything else.</li>
8888
<li><code>--schema</code>: Serialize schemas instead of JSON (use with -b). This will output a binary version of the specified schema that itself corresponds to the reflection/reflection.fbs schema. Loading this binary file is the basis for reflection functionality. </li>
8989
</ul>
9090
</div></div><!-- contents -->

docs/source/Compiler.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ be generated for each file processed:
7171

7272
- `--proto`: Expect input files to be .proto files (protocol buffers).
7373
Output the corresponding .fbs file.
74-
Currently supports: `package`, `message`, `enum`, nested declarations.
75-
Does not support, but will skip without error: `import`, `option`.
76-
Does not support, will generate error: `service`, `extend`, `extensions`,
77-
`oneof`, `group`, custom options.
74+
Currently supports: `package`, `message`, `enum`, nested declarations,
75+
`import` (use `-I` for paths), `extend`, `oneof`, `group`.
76+
Does not support, but will skip without error: `option`, `service`,
77+
`extensions`, and most everything else.
7878

7979
- `--schema`: Serialize schemas instead of JSON (use with -b). This will
8080
output a binary version of the specified schema that itself corresponds

include/flatbuffers/idl.h

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ struct Type {
125125
enum_def(_ed)
126126
{}
127127

128+
bool operator==(const Type &o) {
129+
return base_type == o.base_type && element == o.element &&
130+
struct_def == o.struct_def && enum_def == o.enum_def;
131+
}
132+
128133
Type VectorType() const { return Type(element, struct_def, enum_def); }
129134

130135
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
@@ -163,6 +168,17 @@ template<typename T> class SymbolTable {
163168
return false;
164169
}
165170

171+
void Move(const std::string &oldname, const std::string &newname) {
172+
auto it = dict.find(oldname);
173+
if (it != dict.end()) {
174+
auto obj = it->second;
175+
dict.erase(it);
176+
dict[newname] = obj;
177+
} else {
178+
assert(false);
179+
}
180+
}
181+
166182
T *Lookup(const std::string &name) const {
167183
auto it = dict.find(name);
168184
return it == dict.end() ? nullptr : it->second;
@@ -178,6 +194,13 @@ template<typename T> class SymbolTable {
178194
// A name space, as set in the schema.
179195
struct Namespace {
180196
std::vector<std::string> components;
197+
198+
// Given a (potentally unqualified) name, return the "fully qualified" name
199+
// which has a full namespaced descriptor.
200+
// With max_components you can request less than the number of components
201+
// the current namespace has.
202+
std::string GetFullyQualifiedName(const std::string &name,
203+
size_t max_components = 1000) const;
181204
};
182205

183206
// Base class for all definition types (fields, structs_, enums_).
@@ -293,7 +316,8 @@ class Parser {
293316
cursor_(nullptr),
294317
line_(1),
295318
proto_mode_(proto_mode),
296-
strict_json_(strict_json) {
319+
strict_json_(strict_json),
320+
anonymous_counter(0) {
297321
// Just in case none are declared:
298322
namespaces_.push_back(new Namespace());
299323
known_attributes_.insert("deprecated");
@@ -331,12 +355,6 @@ class Parser {
331355
// Mark all definitions as already having code generated.
332356
void MarkGenerated();
333357

334-
// Given a (potentally unqualified) name, return the "fully qualified" name
335-
// which has a full namespaced descriptor. If the parser has no current
336-
// namespace context, or if the name passed is partially qualified the input
337-
// is simply returned.
338-
std::string GetFullyQualifiedName(const std::string &name) const;
339-
340358
// Get the files recursively included by the given file. The returned
341359
// container will have at least the given file.
342360
std::set<std::string> GetIncludedFilesRecursive(
@@ -351,6 +369,7 @@ class Parser {
351369
void Next();
352370
bool IsNext(int t);
353371
void Expect(int t);
372+
std::string TokenToStringId(int t);
354373
EnumDef *LookupEnum(const std::string &id);
355374
void ParseNamespacing(std::string *id, std::string *last);
356375
void ParseTypeIdent(Type &type);
@@ -369,12 +388,19 @@ class Parser {
369388
void ParseHash(Value &e, FieldDef* field);
370389
void ParseSingleValue(Value &e);
371390
int64_t ParseIntegerFromString(Type &type);
372-
StructDef *LookupCreateStruct(const std::string &name);
373-
void ParseEnum(bool is_union);
391+
StructDef *LookupCreateStruct(const std::string &name,
392+
bool create_if_new = true,
393+
bool definition = false);
394+
EnumDef &ParseEnum(bool is_union);
374395
void ParseNamespace();
375-
StructDef &StartStruct();
396+
StructDef &StartStruct(const std::string &name);
376397
void ParseDecl();
398+
void ParseProtoFields(StructDef *struct_def, bool isextend,
399+
bool inside_oneof);
400+
void ParseProtoOption();
401+
void ParseProtoKey();
377402
void ParseProtoDecl();
403+
void ParseProtoCurliesOrIdent();
378404
Type ParseTypeFromProtoType();
379405

380406
public:
@@ -405,6 +431,8 @@ class Parser {
405431
std::vector<uint8_t> struct_stack_;
406432

407433
std::set<std::string> known_attributes_;
434+
435+
int anonymous_counter;
408436
};
409437

410438
// Utility functions for multiple generators:

src/idl_gen_cpp.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
287287
}
288288
auto nested = field.attributes.Lookup("nested_flatbuffer");
289289
if (nested) {
290-
std::string qualified_name = parser.GetFullyQualifiedName(
291-
nested->constant);
290+
std::string qualified_name =
291+
parser.namespaces_.back()->GetFullyQualifiedName(nested->constant);
292292
auto nested_root = parser.structs_.Lookup(qualified_name);
293293
assert(nested_root); // Guaranteed to exist by parser.
294294
(void)nested_root;
@@ -719,7 +719,8 @@ std::string GenerateCPP(const Parser &parser,
719719
// Generate convenient global helper functions:
720720
if (parser.root_struct_def_) {
721721
auto &name = parser.root_struct_def_->name;
722-
std::string qualified_name = parser.GetFullyQualifiedName(name);
722+
std::string qualified_name =
723+
parser.namespaces_.back()->GetFullyQualifiedName(name);
723724
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
724725

725726
// The root datatype accessor:

src/idl_gen_fbs.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,49 @@ namespace flatbuffers {
2424

2525
static std::string GenType(const Type &type) {
2626
switch (type.base_type) {
27-
case BASE_TYPE_STRUCT: return type.struct_def->name;
28-
case BASE_TYPE_UNION: return type.enum_def->name;
29-
case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]";
30-
default: return kTypeNames[type.base_type];
27+
case BASE_TYPE_STRUCT:
28+
return type.struct_def->defined_namespace->GetFullyQualifiedName(
29+
type.struct_def->name);
30+
case BASE_TYPE_UNION:
31+
return type.enum_def->defined_namespace->GetFullyQualifiedName(
32+
type.enum_def->name);
33+
case BASE_TYPE_VECTOR:
34+
return "[" + GenType(type.VectorType()) + "]";
35+
default:
36+
return kTypeNames[type.base_type];
3137
}
3238
}
3339

40+
static void GenNameSpace(const Namespace &name_space, std::string *_schema,
41+
const Namespace **last_namespace) {
42+
if (*last_namespace == &name_space) return;
43+
*last_namespace = &name_space;
44+
auto &schema = *_schema;
45+
schema += "namespace ";
46+
for (auto it = name_space.components.begin();
47+
it != name_space.components.end(); ++it) {
48+
if (it != name_space.components.begin()) schema += ".";
49+
schema += *it;
50+
}
51+
schema += ";\n\n";
52+
}
53+
3454
// Generate a flatbuffer schema from the Parser's internal representation.
3555
std::string GenerateFBS(const Parser &parser, const std::string &file_name,
3656
const GeneratorOptions &opts) {
57+
// Proto namespaces may clash with table names, so we have to prefix all:
58+
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
59+
++it) {
60+
for (auto comp = (*it)->components.begin(); comp != (*it)->components.end();
61+
++comp) {
62+
(*comp) = "_" + (*comp);
63+
}
64+
}
65+
3766
std::string schema;
3867
schema += "// Generated from " + file_name + ".proto\n\n";
3968
if (opts.include_dependence_headers) {
69+
#ifdef FBS_GEN_INCLUDES // TODO: currently all in one file.
4070
int num_includes = 0;
4171
for (auto it = parser.included_files_.begin();
4272
it != parser.included_files_.end(); ++it) {
@@ -48,19 +78,14 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name,
4878
}
4979
}
5080
if (num_includes) schema += "\n";
81+
#endif
5182
}
52-
schema += "namespace ";
53-
auto name_space = parser.namespaces_.back();
54-
for (auto it = name_space->components.begin();
55-
it != name_space->components.end(); ++it) {
56-
if (it != name_space->components.begin()) schema += ".";
57-
schema += *it;
58-
}
59-
schema += ";\n\n";
6083
// Generate code for all the enum declarations.
84+
const Namespace *last_namespace = nullptr;
6185
for (auto enum_def_it = parser.enums_.vec.begin();
6286
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
6387
EnumDef &enum_def = **enum_def_it;
88+
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
6489
GenComment(enum_def.doc_comment, &schema, nullptr);
6590
schema += "enum " + enum_def.name + " : ";
6691
schema += GenType(enum_def.underlying_type) + " {\n";
@@ -76,6 +101,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name,
76101
for (auto it = parser.structs_.vec.begin();
77102
it != parser.structs_.vec.end(); ++it) {
78103
StructDef &struct_def = **it;
104+
GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
79105
GenComment(struct_def.doc_comment, &schema, nullptr);
80106
schema += "table " + struct_def.name + " {\n";
81107
for (auto field_it = struct_def.fields.vec.begin();

0 commit comments

Comments
 (0)