diff --git a/docs/html/md__compiler.html b/docs/html/md__compiler.html
index 6ae87ed39..9ab104fe9 100644
--- a/docs/html/md__compiler.html
+++ b/docs/html/md__compiler.html
@@ -84,7 +84,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
--gen-mutable : Generate additional non-const accessors for mutating FlatBuffers in-place.
--gen-onefile : Generate single output file (useful for C#)
--raw-binary : Allow binaries without a file_indentifier to be read. This may crash flatc given a mismatched schema.
---proto: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: package, message, enum. Does not support, but will skip without error: import, option. Does not support, will generate error: service, extend, extensions, oneof, group, custom options, nested declarations.
+--proto: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: package, message, enum, nested declarations. Does not support, but will skip without error: import, option. Does not support, will generate error: service, extend, extensions, oneof, group, custom options.
--schema: 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.
diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md
index e4663e172..ebcdd70d6 100755
--- a/docs/source/Compiler.md
+++ b/docs/source/Compiler.md
@@ -71,10 +71,10 @@ be generated for each file processed:
- `--proto`: Expect input files to be .proto files (protocol buffers).
Output the corresponding .fbs file.
- Currently supports: `package`, `message`, `enum`.
+ Currently supports: `package`, `message`, `enum`, nested declarations.
Does not support, but will skip without error: `import`, `option`.
Does not support, will generate error: `service`, `extend`, `extensions`,
- `oneof`, `group`, custom options, nested declarations.
+ `oneof`, `group`, custom options.
- `--schema`: Serialize schemas instead of JSON (use with -b). This will
output a binary version of the specified schema that itself corresponds
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index d5aa31201..c7c9d6d09 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -1052,45 +1052,50 @@ void Parser::ParseProtoDecl() {
struct_def.doc_comment = struct_comment;
Expect('{');
while (token_ != '}') {
- std::vector field_comment = doc_comment_;
- // Parse the qualifier.
- bool required = false;
- bool repeated = false;
- if (attribute_ == "optional") {
- // This is the default.
- } else if (attribute_ == "required") {
- required = true;
- } else if (attribute_ == "repeated") {
- repeated = true;
+ if (attribute_ == "message" || attribute_ == "enum") {
+ // Nested declarations.
+ ParseProtoDecl();
} else {
- Error("expecting optional/required/repeated, got: " + attribute_);
- }
- Type type = ParseTypeFromProtoType();
- // Repeated elements get mapped to a vector.
- if (repeated) {
- type.element = type.base_type;
- type.base_type = BASE_TYPE_VECTOR;
- }
- std::string name = attribute_;
- Expect(kTokenIdentifier);
- // Parse the field id. Since we're just translating schemas, not
- // any kind of binary compatibility, we can safely ignore these, and
- // assign our own.
- Expect('=');
- Expect(kTokenIntegerConstant);
- auto &field = AddField(struct_def, name, type);
- field.doc_comment = field_comment;
- if (!IsScalar(type.base_type)) field.required = required;
- // See if there's a default specified.
- if (IsNext('[')) {
- if (attribute_ != "default") Error("\'default\' expected");
- Next();
+ std::vector field_comment = doc_comment_;
+ // Parse the qualifier.
+ bool required = false;
+ bool repeated = false;
+ if (attribute_ == "optional") {
+ // This is the default.
+ } else if (attribute_ == "required") {
+ required = true;
+ } else if (attribute_ == "repeated") {
+ repeated = true;
+ } else {
+ Error("expecting optional/required/repeated, got: " + attribute_);
+ }
+ Type type = ParseTypeFromProtoType();
+ // Repeated elements get mapped to a vector.
+ if (repeated) {
+ type.element = type.base_type;
+ type.base_type = BASE_TYPE_VECTOR;
+ }
+ std::string name = attribute_;
+ Expect(kTokenIdentifier);
+ // Parse the field id. Since we're just translating schemas, not
+ // any kind of binary compatibility, we can safely ignore these, and
+ // assign our own.
Expect('=');
- field.value.constant = attribute_;
- Next();
- Expect(']');
+ Expect(kTokenIntegerConstant);
+ auto &field = AddField(struct_def, name, type);
+ field.doc_comment = field_comment;
+ if (!IsScalar(type.base_type)) field.required = required;
+ // See if there's a default specified.
+ if (IsNext('[')) {
+ if (attribute_ != "default") Error("\'default\' expected");
+ Next();
+ Expect('=');
+ field.value.constant = attribute_;
+ Next();
+ Expect(']');
+ }
+ Expect(';');
}
- Expect(';');
}
Next();
} else if (attribute_ == "enum") {
diff --git a/tests/prototest/test.golden b/tests/prototest/test.golden
index 767a8bc0a..7082ad2d8 100644
--- a/tests/prototest/test.golden
+++ b/tests/prototest/test.golden
@@ -9,12 +9,6 @@ enum ProtoEnum : short {
BAR = 5,
}
-table OtherMessage {
- a:double;
- /// doc comment for b.
- b:float = 3.14149;
-}
-
/// 2nd table doc comment with
/// many lines.
table ProtoMessage {
@@ -39,3 +33,9 @@ table ProtoMessage {
o:[string];
}
+table OtherMessage {
+ a:double;
+ /// doc comment for b.
+ b:float = 3.14149;
+}
+
diff --git a/tests/prototest/test.proto b/tests/prototest/test.proto
index 0ca4a2a6a..af5b66d75 100644
--- a/tests/prototest/test.proto
+++ b/tests/prototest/test.proto
@@ -12,16 +12,16 @@ enum ProtoEnum {
BAR = 5;
}
-// Ignored non-doc comment.
-message OtherMessage {
- optional double a = 26;
- /// doc comment for b.
- optional float b = 32 [default = 3.14149];
-}
-
/// 2nd table doc comment with
/// many lines.
message ProtoMessage {
+ // Ignored non-doc comment.
+ // A nested message declaration, will be moved to top level in .fbs
+ message OtherMessage {
+ optional double a = 26;
+ /// doc comment for b.
+ optional float b = 32 [default = 3.14149];
+ }
optional int32 c = 12 [default = 16];
optional int64 d = 1 [default = 0];
optional uint32 p = 1;