summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRichard A Hofer <rofer@google.com>2021-01-04 15:18:19 -0500
committerGitHub <noreply@github.com>2021-01-04 12:18:19 -0800
commit24dd85fd28b002d1dc6bca331b3e9516ea55c8cf (patch)
tree50ecea1e0b4004336cc74475b5be49abe548707c /src
parent57f68e28964c050190bc9d0242d76be56d898c78 (diff)
downloadflatbuffers-24dd85fd28b002d1dc6bca331b3e9516ea55c8cf.tar.gz
flatbuffers-24dd85fd28b002d1dc6bca331b3e9516ea55c8cf.tar.bz2
flatbuffers-24dd85fd28b002d1dc6bca331b3e9516ea55c8cf.zip
Generate code to encode and decode nested flatbuffers in Python. (#6354)
* Generate code to encode and decode nested flatbuffers in Python. * Delete accidental trailing whitespace. * Fully delete trailing whitespace.
Diffstat (limited to 'src')
-rw-r--r--src/idl_gen_python.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp
index 43290d32..c342650b 100644
--- a/src/idl_gen_python.cpp
+++ b/src/idl_gen_python.cpp
@@ -408,6 +408,39 @@ class PythonGenerator : public BaseGenerator {
code += "\n";
}
+ // Returns a nested flatbuffer as itself.
+ void GetVectorAsNestedFlatbuffer(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr) {
+ auto nested = field.attributes.Lookup("nested_flatbuffer");
+ if (!nested) { return; } // There is no nested flatbuffer.
+
+ std::string unqualified_name = nested->constant;
+ std::string qualified_name = nested->constant;
+ auto nested_root = parser_.LookupStruct(nested->constant);
+ if (nested_root == nullptr) {
+ qualified_name = parser_.current_namespace_->GetFullyQualifiedName(
+ nested->constant);
+ nested_root = parser_.LookupStruct(qualified_name);
+ }
+ FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser.
+ (void)nested_root;
+
+ auto &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field)) + "NestedRoot(self):";
+
+ code += OffsetPrefix(field);
+
+ code += Indent + Indent + Indent;
+ code += "from " + qualified_name + " import " + unqualified_name + "\n";
+ code += Indent + Indent + Indent + "return " + unqualified_name;
+ code += ".GetRootAs" + unqualified_name;
+ code += "(self._tab.Bytes, self._tab.Vector(o))\n";
+ code += Indent + Indent + "return 0\n";
+ code += "\n";
+ }
+
// Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
@@ -561,6 +594,43 @@ class PythonGenerator : public BaseGenerator {
code += ")\n";
}
+ // Set the value of one of the members of a table's vector and fills in the
+ // elements from a bytearray. This is for simplifying the use of nested
+ // flatbuffers.
+ void BuildVectorOfTableFromBytes(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr) {
+ auto nested = field.attributes.Lookup("nested_flatbuffer");
+ if (!nested) { return; } // There is no nested flatbuffer.
+
+ std::string unqualified_name = nested->constant;
+ std::string qualified_name = nested->constant;
+ auto nested_root = parser_.LookupStruct(nested->constant);
+ if (nested_root == nullptr) {
+ qualified_name =
+ parser_.current_namespace_->GetFullyQualifiedName(nested->constant);
+ nested_root = parser_.LookupStruct(qualified_name);
+ }
+ FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser.
+ (void)nested_root;
+
+ auto &code = *code_ptr;
+ code += "def " + NormalizedName(struct_def) + "Make";
+ code += MakeCamel(NormalizedName(field));
+ code += "VectorFromBytes(builder, bytes):\n";
+ code += Indent + "builder.StartVector(";
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ code += NumToString(elem_size);
+ code += ", len(bytes), " + NumToString(alignment);
+ code += ")\n";
+ code += Indent + "builder.head = builder.head - len(bytes)\n";
+ code += Indent + "builder.Bytes[builder.head : builder.head + len(bytes)]";
+ code += " = bytes\n";
+ code += Indent + "return builder.EndVector(len(bytes))\n";
+ }
+
// Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
auto &code = *code_ptr;
@@ -607,6 +677,7 @@ class PythonGenerator : public BaseGenerator {
} else {
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
+ GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr);
}
break;
}
@@ -643,6 +714,7 @@ class PythonGenerator : public BaseGenerator {
BuildFieldOfTable(struct_def, field, offset, code_ptr);
if (IsVector(field.value.type)) {
BuildVectorOfTable(struct_def, field, code_ptr);
+ BuildVectorOfTableFromBytes(struct_def, field, code_ptr);
}
}