// Set the value of a table's field. static void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field, const size_t offset, std::string *code_ptr) { std::string &code = *code_ptr; code += "func " + struct_def.name + "Add" + MakeCamel(field.name); code += "(builder *flatbuffers.Builder, "; code += MakeCamel(field.name, false) + " "; if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { code += "flatbuffers.UOffsetT"; } else { code += GenTypeBasic(field.value.type); } code += ") {\n"; code += "\tbuilder.Prepend"; code += GenMethod(field) + "Slot("; code += NumToString(offset) + ", "; if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { code += "flatbuffers.UOffsetT"; code += "("; code += MakeCamel(field.name, false) + ")"; } else { code += MakeCamel(field.name, false); } code += ", " + field.value.constant; code += ")\n}\n"; }
// Mutate the value of a struct's scalar. static void MutateScalarFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string setter = "rcv._tab.Mutate" + type; GenReceiver(struct_def, code_ptr); code += " Mutate" + MakeCamel(field.name); code += "(n " + TypeName(field) + ") bool {\n\treturn " + setter; code += "(rcv._tab.Pos+flatbuffers.UOffsetT("; code += NumToString(field.value.offset) + "), n)\n}\n\n"; }
// Mutate the value of a table's scalar. static void MutateScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string setter = "rcv._tab.Mutate" + type + "Slot"; GenReceiver(struct_def, code_ptr); code += " Mutate" + MakeCamel(field.name); code += "(n " + TypeName(field) + ") bool {\n\treturn "; code += setter + "(" + NumToString(field.value.offset) + ", n)\n"; code += "}\n\n"; }
// Returns the function name that is able to read a value of the given type. static std::string GenGetter(const Type &type) { switch (type.base_type) { case BASE_TYPE_STRING: return "rcv._tab.ByteVector"; case BASE_TYPE_UNION: return "rcv._tab.Union"; case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); default: return "rcv._tab.Get" + MakeCamel(GenTypeGet(type)); } }
// Get a struct by initializing an existing struct. // Specific to Struct. static void GetStructFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self, obj):\n"; code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + "; code += NumToString(field.value.offset) + ")"; code += "\n" + Indent + Indent + "return obj\n\n"; }
// Get the value of a struct's scalar. static void GetScalarFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; std::string getter = GenGetter(field.value.type); GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "() " + TypeName(field) + " { return " + getter; code += "(rcv._tab.Pos + flatbuffers.UOffsetT("; code += NumToString(field.value.offset) + ")) }\n"; }
// Get the length of a vector. static void GetVectorLen(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name) + "Length(self"; code += "):" + OffsetPrefix(field); code += Indent + Indent + Indent + "return self._tab.VectorLen(o)\n"; code += Indent + Indent + "return 0\n\n"; }
// Get the length of a vector. static void GetVectorLen(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name) + "Length("; code += ") int " + OffsetPrefix(field); code += "\t\treturn rcv._tab.VectorLen(o)\n\t}\n"; code += "\treturn 0\n}\n\n"; }
// Get the value of a string. static void GetStringField(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "() " + TypeName(field) + " "; code += OffsetPrefix(field) + "\t\treturn " + GenGetter(field.value.type); code += "(o + rcv._tab.Pos)\n\t}\n\treturn nil\n"; code += "}\n\n"; }
// Get the value of a struct's scalar. static void GetScalarFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; std::string getter = GenGetter(field.value.type); GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self): return " + getter; code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type("; code += NumToString(field.value.offset) + "))\n"; }
// Set the value of one of the members of a table's vector. static void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; code += "func " + struct_def.name + "Start"; code += MakeCamel(field.name); code += "Vector(builder *flatbuffers.Builder, numElems int) "; code += "flatbuffers.UOffsetT { return builder.StartVector("; code += NumToString(InlineSize(field.value.type.VectorType())); code += ", numElems) }\n"; }
// Returns the function name that is able to read a value of the given type. static std::string GenGetter(const Type &type) { switch (type.base_type) { case BASE_TYPE_STRING: return "self._tab.String("; case BASE_TYPE_UNION: return "self._tab.Union("; case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); default: return "self._tab.Get(flatbuffers.number_types." + \ MakeCamel(GenTypeGet(type)) + \ "Flags, "; } }
// Get a [ubyte] vector as a byte slice. static void GetUByteSlice(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name) + "Bytes("; code += ") []byte " + OffsetPrefix(field); code += "\t\treturn rcv._tab.ByteVector(o + rcv._tab.Pos)\n\t}\n"; code += "\treturn nil\n}\n\n"; }
// Returns the function name that is able to read a value of the given type. static std::string GenGetter(const Type &type) { switch (type.base_type) { case BASE_TYPE_STRING: return "__string"; case BASE_TYPE_STRUCT: return "__struct"; case BASE_TYPE_UNION: return "__union"; case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); default: return "bb.get" + (SizeOf(type.base_type) > 1 ? MakeCamel(GenTypeGet(type)) : ""); } }
// Get the value of a string. static void GetStringField(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self):"; code += OffsetPrefix(field); code += Indent + Indent + Indent + "return " + GenGetter(field.value.type); code += "o + self._tab.Pos)\n"; code += Indent + Indent + "return \"\"\n\n"; }
// Get the value of a union from an object. static void GetUnionField(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name) + "("; code += "obj " + TypeName(field) + ") bool "; code += OffsetPrefix(field); code += "\t\t" + GenGetter(field.value.type); code += "(obj, o)\n\t\treturn true\n\t}\n"; code += "\treturn false\n"; code += "}\n\n"; }
// Set the value of one of the members of a table's vector. static void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; code += "def " + struct_def.name + "Start"; code += MakeCamel(field.name); code += "Vector(builder, numElems): return 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 += ", numElems, " + NumToString(alignment); code += ")\n"; }
// Get a struct by initializing an existing struct. // Specific to Struct. static void GetStructFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "(obj *" + TypeName(field); code += ") *" + TypeName(field); code += " {\n"; code += "\tif obj == nil {\n"; code += "\t\tobj = new(" + TypeName(field) + ")\n"; code += "\t}\n"; code += "\tobj.Init(rcv._tab.Bytes, rcv._tab.Pos+"; code += NumToString(field.value.offset) + ")"; code += "\n\treturn obj\n"; code += "}\n"; }
// Recusively generate struct construction statements of the form: // builder.putType(name); // and insert manual padding. static void GenStructBody(const StructDef &struct_def, std::string *code_ptr, const char *nameprefix) { std::string &code = *code_ptr; code += " builder.prep(" + NumToString(struct_def.minalign) + ", 0);\n"; for (auto it = struct_def.fields.vec.rbegin(); it != struct_def.fields.vec.rend(); ++it) { auto &field = **it; if (field.padding) code += " builder.pad(" + NumToString(field.padding) + ");\n"; if (IsStruct(field.value.type)) { GenStructBody(*field.value.type.struct_def, code_ptr, (field.value.type.struct_def->name + "_").c_str()); } else { code += " builder.put" + GenMethod(field) + "("; code += nameprefix + MakeCamel(field.name, false) + ");\n"; } } }
// Recursively generate arguments for a constructor, to deal with nested // structs. static void GenStructArgs(const StructDef &struct_def, std::string *code_ptr, const char *nameprefix) { std::string &code = *code_ptr; for (auto it = struct_def.fields.vec.begin(); it != struct_def.fields.vec.end(); ++it) { auto &field = **it; if (IsStruct(field.value.type)) { // Generate arguments for a struct inside a struct. To ensure names // don't clash, and to make it obvious these arguments are constructing // a nested struct, prefix the name with the struct name. GenStructArgs(*field.value.type.struct_def, code_ptr, (field.value.type.struct_def->name + "_").c_str()); } else { code += ", " + GenTypeBasic(field.value.type) + " " + nameprefix; code += MakeCamel(field.name, false); } } }
// Get the value of a union from an object. static void GetUnionField(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name) + "(self):"; code += OffsetPrefix(field); // TODO(rw): this works and is not the good way to it: bool is_native_table = TypeName(field) == "*flatbuffers.Table"; if (is_native_table) { code += Indent + Indent + Indent + "from flatbuffers.table import Table\n"; } else { code += Indent + Indent + Indent; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; } code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n"; code += Indent + Indent + Indent + GenGetter(field.value.type); code += "obj, o)\n" + Indent + Indent + Indent + "return obj\n"; code += Indent + Indent + "return None\n\n"; }
// Get a struct by initializing an existing struct. // Specific to Table. static void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self):"; code += OffsetPrefix(field); if (field.value.type.struct_def->fixed) { code += Indent + Indent + Indent + "x = o + self._tab.Pos\n"; } else { code += Indent + Indent + Indent; code += "x = self._tab.Indirect(o + self._tab.Pos)\n"; } code += Indent + Indent + Indent; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n"; code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n"; code += Indent + Indent + Indent + "return obj\n"; code += Indent + Indent + "return None\n\n"; }
// Get the value of a vector's struct member. static void GetMemberOfVectorOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; auto vectortype = field.value.type.VectorType(); GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "(obj *" + TypeName(field); code += ", j int) bool " + OffsetPrefix(field); code += "\t\tx := rcv._tab.Vector(o)\n"; code += "\t\tx += flatbuffers.UOffsetT(j) * "; code += NumToString(InlineSize(vectortype)) + "\n"; if (!(vectortype.struct_def->fixed)) { code += "\t\tx = rcv._tab.Indirect(x)\n"; } code += "\t\tobj.Init(rcv._tab.Bytes, x)\n"; code += "\t\treturn true\n\t}\n"; code += "\treturn false\n"; code += "}\n\n"; }
// Get a struct by initializing an existing struct. // Specific to Table. static void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "(obj *"; code += TypeName(field); code += ") *" + TypeName(field) + " " + OffsetPrefix(field); if (field.value.type.struct_def->fixed) { code += "\t\tx := o + rcv._tab.Pos\n"; } else { code += "\t\tx := rcv._tab.Indirect(o + rcv._tab.Pos)\n"; } code += "\t\tif obj == nil {\n"; code += "\t\t\tobj = new(" + TypeName(field) + ")\n"; code += "\t\t}\n"; code += "\t\tobj.Init(rcv._tab.Bytes, x)\n"; code += "\t\treturn obj\n\t}\n\treturn nil\n"; code += "}\n\n"; }
// Recursively generate arguments for a constructor, to deal with nested // structs. static void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix, std::string *code_ptr) { for (auto it = struct_def.fields.vec.begin(); it != struct_def.fields.vec.end(); ++it) { auto &field = **it; if (IsStruct(field.value.type)) { // Generate arguments for a struct inside a struct. To ensure names // don't clash, and to make it obvious these arguments are constructing // a nested struct, prefix the name with the field name. StructBuilderArgs(*field.value.type.struct_def, (nameprefix + (field.name + "_")).c_str(), code_ptr); } else { std::string &code = *code_ptr; code += (std::string)", " + nameprefix; code += MakeCamel(field.name, false); } } }
// Recursively generate struct construction statements and instert manual // padding. static void StructBuilderBody(const StructDef &struct_def, const char *nameprefix, std::string *code_ptr) { std::string &code = *code_ptr; code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", "; code += NumToString(struct_def.bytesize) + ")\n"; for (auto it = struct_def.fields.vec.rbegin(); it != struct_def.fields.vec.rend(); ++it) { auto &field = **it; if (field.padding) code += "\tbuilder.Pad(" + NumToString(field.padding) + ")\n"; if (IsStruct(field.value.type)) { StructBuilderBody(*field.value.type.struct_def, (nameprefix + (field.name + "_")).c_str(), code_ptr); } else { code += "\tbuilder.Prepend" + GenMethod(field) + "("; code += nameprefix + MakeCamel(field.name, false) + ")\n"; } } }
// Get the value of a vector's non-struct member. Uses a named return // argument to conveniently set the zero value for the result. static void GetMemberOfVectorOfNonStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; auto vectortype = field.value.type.VectorType(); GenReceiver(struct_def, code_ptr); code += " " + MakeCamel(field.name); code += "(j int) " + TypeName(field) + " "; code += OffsetPrefix(field); code += "\t\ta := rcv._tab.Vector(o)\n"; code += "\t\treturn " + GenGetter(field.value.type) + "("; code += "a + flatbuffers.UOffsetT(j*"; code += NumToString(InlineSize(vectortype)) + "))\n"; code += "\t}\n"; if (vectortype.base_type == BASE_TYPE_STRING) { code += "\treturn nil\n"; } else { code += "\treturn 0\n"; } code += "}\n\n"; }
// Get the value of a vector's non-struct member. Uses a named return // argument to conveniently set the zero value for the result. static void GetMemberOfVectorOfNonStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; auto vectortype = field.value.type.VectorType(); GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self, j):"; code += OffsetPrefix(field); code += Indent + Indent + Indent + "a = self._tab.Vector(o)\n"; code += Indent + Indent + Indent; code += "return " + GenGetter(field.value.type); code += "a + flatbuffers.number_types.UOffsetTFlags.py_type(j * "; code += NumToString(InlineSize(vectortype)) + "))\n"; if (vectortype.base_type == BASE_TYPE_STRING) { code += Indent + Indent + "return \"\"\n"; } else { code += Indent + Indent + "return 0\n"; } code += "\n"; }
// Get the value of a vector's struct member. static void GetMemberOfVectorOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { std::string &code = *code_ptr; auto vectortype = field.value.type.VectorType(); GenReceiver(struct_def, code_ptr); code += MakeCamel(field.name); code += "(self, j):" + OffsetPrefix(field); code += Indent + Indent + Indent + "x = self._tab.Vector(o)\n"; code += Indent + Indent + Indent; code += "x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * "; code += NumToString(InlineSize(vectortype)) + "\n"; if (!(vectortype.struct_def->fixed)) { code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n"; } code += Indent + Indent + Indent; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n"; code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n"; code += Indent + Indent + Indent + "return obj\n"; code += Indent + Indent + "return None\n\n"; }
// Returns the method name for use with add/put calls. static std::string GenMethod(const FieldDef &field) { return IsScalar(field.value.type.base_type) ? MakeCamel(GenTypeBasic(field.value.type)) : (IsStruct(field.value.type) ? "Struct" : "UOffsetT"); }