Make string/vector field serialization order not depend on optimizer.

Multiple calls of e.g. CreateString inside a call to a CreateTable
could cause those strings to end up in different locations in the
wire format, since order or argument evaluation is undefined.

This is allowed by the FlatBuffer format, but it is not helpful,
especially when debugging the contents of binaries, or comparing
against a "golden" binary for tests etc.

Now making sure that all the CreateTableDirect calls first serialize
sub strings/vectors before calling CreateTable.

Also made similar changes to the serialization of "binary schemas".

Change-Id: I5747c4038b37a0d400aca2bc592bec751cf5c172
This commit is contained in:
Wouter van Oortmerssen 2018-11-16 16:22:18 -08:00
parent 5f32f94810
commit f575b02fda
7 changed files with 192 additions and 133 deletions

View File

@ -222,10 +222,12 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
const char *key = nullptr, const char *key = nullptr,
const char *value = nullptr) { const char *value = nullptr) {
auto key__ = key ? _fbb.CreateString(key) : 0;
auto value__ = value ? _fbb.CreateString(value) : 0;
return reflection::CreateKeyValue( return reflection::CreateKeyValue(
_fbb, _fbb,
key ? _fbb.CreateString(key) : 0, key__,
value ? _fbb.CreateString(value) : 0); value__);
} }
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -327,13 +329,15 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
flatbuffers::Offset<Object> object = 0, flatbuffers::Offset<Object> object = 0,
flatbuffers::Offset<Type> union_type = 0, flatbuffers::Offset<Type> union_type = 0,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateEnumVal( return reflection::CreateEnumVal(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
value, value,
object, object,
union_type, union_type,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -451,14 +455,18 @@ inline flatbuffers::Offset<Enum> CreateEnumDirect(
flatbuffers::Offset<Type> underlying_type = 0, flatbuffers::Offset<Type> underlying_type = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateEnum( return reflection::CreateEnum(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0, values__,
is_union, is_union,
underlying_type, underlying_type,
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0, attributes__,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -628,9 +636,12 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
bool key = false, bool key = false,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateField( return reflection::CreateField(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
type, type,
id, id,
offset, offset,
@ -639,8 +650,8 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
deprecated, deprecated,
required, required,
key, key,
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0, attributes__,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -767,15 +778,19 @@ inline flatbuffers::Offset<Object> CreateObjectDirect(
int32_t bytesize = 0, int32_t bytesize = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateObject( return reflection::CreateObject(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0, fields__,
is_struct, is_struct,
minalign, minalign,
bytesize, bytesize,
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0, attributes__,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -881,13 +896,16 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
flatbuffers::Offset<Object> response = 0, flatbuffers::Offset<Object> response = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateRPCCall( return reflection::CreateRPCCall(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
request, request,
response, response,
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0, attributes__,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -980,12 +998,16 @@ inline flatbuffers::Offset<Service> CreateServiceDirect(
const std::vector<flatbuffers::Offset<RPCCall>> *calls = nullptr, const std::vector<flatbuffers::Offset<RPCCall>> *calls = nullptr,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<RPCCall>>(*calls) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateService( return reflection::CreateService(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
calls ? _fbb.CreateVector<flatbuffers::Offset<RPCCall>>(*calls) : 0, calls__,
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0, attributes__,
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0); documentation__);
} }
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -1097,14 +1119,19 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect(
const char *file_ext = nullptr, const char *file_ext = nullptr,
flatbuffers::Offset<Object> root_table = 0, flatbuffers::Offset<Object> root_table = 0,
const std::vector<flatbuffers::Offset<Service>> *services = nullptr) { const std::vector<flatbuffers::Offset<Service>> *services = nullptr) {
auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0;
auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0;
auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<Service>>(*services) : 0;
return reflection::CreateSchema( return reflection::CreateSchema(
_fbb, _fbb,
objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0, objects__,
enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0, enums__,
file_ident ? _fbb.CreateString(file_ident) : 0, file_ident__,
file_ext ? _fbb.CreateString(file_ext) : 0, file_ext__,
root_table, root_table,
services ? _fbb.CreateVector<flatbuffers::Offset<Service>>(*services) : 0); services__);
} }
inline const reflection::Schema *GetSchema(const void *buf) { inline const reflection::Schema *GetSchema(const void *buf) {

View File

@ -408,15 +408,18 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr, const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr,
Equipment equipped_type = Equipment_NONE, Equipment equipped_type = Equipment_NONE,
flatbuffers::Offset<void> equipped = 0) { flatbuffers::Offset<void> equipped = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0;
return MyGame::Sample::CreateMonster( return MyGame::Sample::CreateMonster(
_fbb, _fbb,
pos, pos,
mana, mana,
hp, hp,
name ? _fbb.CreateString(name) : 0, name__,
inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0, inventory__,
color, color,
weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0, weapons__,
equipped_type, equipped_type,
equipped); equipped);
} }
@ -506,9 +509,10 @@ inline flatbuffers::Offset<Weapon> CreateWeaponDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr, const char *name = nullptr,
int16_t damage = 0) { int16_t damage = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0;
return MyGame::Sample::CreateWeapon( return MyGame::Sample::CreateWeapon(
_fbb, _fbb,
name ? _fbb.CreateString(name) : 0, name__,
damage); damage);
} }

View File

@ -2060,36 +2060,30 @@ class CppGenerator : public BaseGenerator {
// Generate a CreateXDirect function with vector types as parameters // Generate a CreateXDirect function with vector types as parameters
if (has_string_or_vector_fields) { if (has_string_or_vector_fields) {
code_ += code_ += "inline flatbuffers::Offset<{{STRUCT_NAME}}> "
"inline flatbuffers::Offset<{{STRUCT_NAME}}> " "Create{{STRUCT_NAME}}Direct(";
"Create{{STRUCT_NAME}}Direct(";
code_ += " flatbuffers::FlatBufferBuilder &_fbb\\"; code_ += " flatbuffers::FlatBufferBuilder &_fbb\\";
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (!field.deprecated) { GenParam(field, true, ",\n "); } if (!field.deprecated) { GenParam(field, true, ",\n "); }
} }
// Need to call "Create" with the struct namespace. // Need to call "Create" with the struct namespace.
const auto qualified_create_name = const auto qualified_create_name =
struct_def.defined_namespace->GetFullyQualifiedName("Create"); struct_def.defined_namespace->GetFullyQualifiedName("Create");
code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name)); code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name));
code_ += ") {"; code_ += ") {";
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
code_ += " _fbb\\";
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (!field.deprecated) { if (!field.deprecated) {
code_.SetValue("FIELD_NAME", Name(field)); code_.SetValue("FIELD_NAME", Name(field));
if (field.value.type.base_type == BASE_TYPE_STRING) { if (field.value.type.base_type == BASE_TYPE_STRING) {
code_ += code_ +=
",\n {{FIELD_NAME}} ? " " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.CreateString({{FIELD_NAME}}) : 0\\"; "_fbb.CreateString({{FIELD_NAME}}) : 0;";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) { } else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code_ += ",\n {{FIELD_NAME}} ? \\"; code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
const auto vtype = field.value.type.VectorType(); const auto vtype = field.value.type.VectorType();
if (IsStruct(vtype)) { if (IsStruct(vtype)) {
const auto type = WrapInNameSpace(*vtype.struct_def); const auto type = WrapInNameSpace(*vtype.struct_def);
@ -2098,9 +2092,21 @@ class CppGenerator : public BaseGenerator {
const auto type = GenTypeWire(vtype, "", false); const auto type = GenTypeWire(vtype, "", false);
code_ += "_fbb.CreateVector<" + type + ">\\"; code_ += "_fbb.CreateVector<" + type + ">\\";
} }
code_ += "(*{{FIELD_NAME}}) : 0\\"; code_ += "(*{{FIELD_NAME}}) : 0;";
} else { }
code_ += ",\n {{FIELD_NAME}}\\"; }
}
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
code_ += " _fbb\\";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
if (!field.deprecated) {
code_.SetValue("FIELD_NAME", Name(field));
code_ += ",\n {{FIELD_NAME}}\\";
if (field.value.type.base_type == BASE_TYPE_STRING ||
field.value.type.base_type == BASE_TYPE_VECTOR) {
code_ += "__\\";
} }
} }
} }

View File

@ -2652,14 +2652,15 @@ void Parser::Serialize() {
service_offsets.push_back(offset); service_offsets.push_back(offset);
(*it)->serialized_location = offset.o; (*it)->serialized_location = offset.o;
} }
auto schema_offset = reflection::CreateSchema( auto objs__ = builder_.CreateVectorOfSortedTables(&object_offsets);
builder_, auto enum__ = builder_.CreateVectorOfSortedTables(&enum_offsets);
builder_.CreateVectorOfSortedTables(&object_offsets), auto fiid__ = builder_.CreateString(file_identifier_);
builder_.CreateVectorOfSortedTables(&enum_offsets), auto fext__ = builder_.CreateString(file_extension_);
builder_.CreateString(file_identifier_), auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
builder_.CreateString(file_extension_), auto schema_offset =
(root_struct_def_ ? root_struct_def_->serialized_location : 0), reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__,
builder_.CreateVectorOfSortedTables(&service_offsets)); (root_struct_def_ ? root_struct_def_->serialized_location : 0),
serv__);
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
} else { } else {
@ -2675,49 +2676,49 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
builder, static_cast<uint16_t>(it - fields.vec.begin()), parser)); builder, static_cast<uint16_t>(it - fields.vec.begin()), parser));
} }
auto qualified_name = defined_namespace->GetFullyQualifiedName(name); auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
return reflection::CreateObject( auto name__ = builder->CreateString(qualified_name);
*builder, auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets);
builder->CreateString(qualified_name), auto attr__ = SerializeAttributes(builder, parser);
builder->CreateVectorOfSortedTables(&field_offsets), auto docs__ = parser.opts.binary_schema_comments
fixed, ? builder->CreateVectorOfStrings(doc_comment)
static_cast<int>(minalign), : 0;
static_cast<int>(bytesize), return reflection::CreateObject(*builder, name__, flds__, fixed,
SerializeAttributes(builder, parser), static_cast<int>(minalign),
parser.opts.binary_schema_comments static_cast<int>(bytesize),
? builder->CreateVectorOfStrings(doc_comment) attr__, docs__);
: 0);
} }
Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder, Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
uint16_t id, uint16_t id,
const Parser &parser) const { const Parser &parser) const {
return reflection::CreateField( auto name__ = builder->CreateString(name);
*builder, builder->CreateString(name), value.type.Serialize(builder), id, auto type__ = value.type.Serialize(builder);
value.offset, auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment)
: 0;
return reflection::CreateField(*builder, name__, type__, id, value.offset,
// Is uint64>max(int64) tested? // Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double) // result may be platform-dependent if underlying is float (not double)
IsFloat(value.type.base_type) ? strtod(value.constant.c_str(), nullptr) IsFloat(value.type.base_type) ? strtod(value.constant.c_str(), nullptr)
: 0.0, : 0.0,
deprecated, required, key, SerializeAttributes(builder, parser), deprecated, required, key, attr__, docs__);
parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment)
: 0);
// TODO: value.constant is almost always "0", we could save quite a bit of // TODO: value.constant is almost always "0", we could save quite a bit of
// space by sharing it. Same for common values of value.type. // space by sharing it. Same for common values of value.type.
} }
Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder, Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
const Parser &parser) const { const Parser &parser) const {
return reflection::CreateRPCCall( auto name__ = builder->CreateString(name);
*builder, auto attr__ = SerializeAttributes(builder, parser);
builder->CreateString(name), auto docs__ = parser.opts.binary_schema_comments
request->serialized_location, ? builder->CreateVectorOfStrings(doc_comment)
response->serialized_location, : 0;
SerializeAttributes(builder, parser), return reflection::CreateRPCCall(*builder, name__,
parser.opts.binary_schema_comments request->serialized_location,
? builder->CreateVectorOfStrings(doc_comment) response->serialized_location,
: 0); attr__, docs__);
} }
Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder, Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
@ -2727,14 +2728,13 @@ Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
servicecall_offsets.push_back((*it)->Serialize(builder, parser)); servicecall_offsets.push_back((*it)->Serialize(builder, parser));
} }
auto qualified_name = defined_namespace->GetFullyQualifiedName(name); auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
return reflection::CreateService( auto name__ = builder->CreateString(qualified_name);
*builder, auto call__ = builder->CreateVector(servicecall_offsets);
builder->CreateString(qualified_name), auto attr__ = SerializeAttributes(builder, parser);
builder->CreateVector(servicecall_offsets), auto docs__ = parser.opts.binary_schema_comments
SerializeAttributes(builder, parser), ? builder->CreateVectorOfStrings(doc_comment)
parser.opts.binary_schema_comments : 0;
? builder->CreateVectorOfStrings(doc_comment) return reflection::CreateService(*builder, name__, call__, attr__, docs__);
: 0);
} }
Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder, Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
@ -2744,29 +2744,27 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
enumval_offsets.push_back((*it)->Serialize(builder, parser)); enumval_offsets.push_back((*it)->Serialize(builder, parser));
} }
auto qualified_name = defined_namespace->GetFullyQualifiedName(name); auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
return reflection::CreateEnum( auto name__ = builder->CreateString(qualified_name);
*builder, auto vals__ = builder->CreateVector(enumval_offsets);
builder->CreateString(qualified_name), auto type__ = underlying_type.Serialize(builder);
builder->CreateVector(enumval_offsets), auto attr__ = SerializeAttributes(builder, parser);
is_union, auto docs__ = parser.opts.binary_schema_comments
underlying_type.Serialize(builder), ? builder->CreateVectorOfStrings(doc_comment)
SerializeAttributes(builder, parser), : 0;
parser.opts.binary_schema_comments return reflection::CreateEnum(*builder, name__, vals__, is_union, type__,
? builder->CreateVectorOfStrings(doc_comment) attr__, docs__);
: 0);
} }
Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder, Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
const Parser &parser) const { const Parser &parser) const {
return reflection::CreateEnumVal( auto name__ = builder->CreateString(name);
*builder, auto type__ = union_type.Serialize(builder);
builder->CreateString(name), auto docs__ = parser.opts.binary_schema_comments
value, ? builder->CreateVectorOfStrings(doc_comment)
: 0;
return reflection::CreateEnumVal(*builder, name__, value,
union_type.struct_def ? union_type.struct_def->serialized_location : 0, union_type.struct_def ? union_type.struct_def->serialized_location : 0,
union_type.Serialize(builder), type__, docs__);
parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment)
: 0);
} }
Offset<reflection::Type> Type::Serialize(FlatBufferBuilder *builder) const { Offset<reflection::Type> Type::Serialize(FlatBufferBuilder *builder) const {
@ -2786,9 +2784,9 @@ Definition::SerializeAttributes(FlatBufferBuilder *builder,
auto it = parser.known_attributes_.find(kv->first); auto it = parser.known_attributes_.find(kv->first);
FLATBUFFERS_ASSERT(it != parser.known_attributes_.end()); FLATBUFFERS_ASSERT(it != parser.known_attributes_.end());
if (parser.opts.binary_schema_builtins || !it->second) { if (parser.opts.binary_schema_builtins || !it->second) {
attrs.push_back(reflection::CreateKeyValue( auto key = builder->CreateString(kv->first);
*builder, builder->CreateString(kv->first), auto val = builder->CreateString(kv->second->constant);
builder->CreateString(kv->second->constant))); attrs.push_back(reflection::CreateKeyValue(*builder, key, val));
} }
} }
if (attrs.size()) { if (attrs.size()) {

Binary file not shown.

View File

@ -931,9 +931,10 @@ inline flatbuffers::Offset<Stat> CreateStatDirect(
const char *id = nullptr, const char *id = nullptr,
int64_t val = 0, int64_t val = 0,
uint16_t count = 0) { uint16_t count = 0) {
auto id__ = id ? _fbb.CreateString(id) : 0;
return MyGame::Example::CreateStat( return MyGame::Example::CreateStat(
_fbb, _fbb,
id ? _fbb.CreateString(id) : 0, id__,
val, val,
count); count);
} }
@ -1923,21 +1924,40 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
AnyAmbiguousAliases any_ambiguous_type = AnyAmbiguousAliases_NONE, AnyAmbiguousAliases any_ambiguous_type = AnyAmbiguousAliases_NONE,
flatbuffers::Offset<void> any_ambiguous = 0, flatbuffers::Offset<void> any_ambiguous = 0,
const std::vector<int8_t> *vector_of_enums = nullptr) { const std::vector<int8_t> *vector_of_enums = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
auto test4__ = test4 ? _fbb.CreateVectorOfStructs<Test>(*test4) : 0;
auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(*testarrayoftables) : 0;
auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfStructs<Ability>(*testarrayofsortedstruct) : 0;
auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
auto test5__ = test5 ? _fbb.CreateVectorOfStructs<Test>(*test5) : 0;
auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_referrables) : 0;
auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_strong_referrables) : 0;
auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<int8_t>(*vector_of_enums) : 0;
return MyGame::Example::CreateMonster( return MyGame::Example::CreateMonster(
_fbb, _fbb,
pos, pos,
mana, mana,
hp, hp,
name ? _fbb.CreateString(name) : 0, name__,
inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0, inventory__,
color, color,
test_type, test_type,
test, test,
test4 ? _fbb.CreateVectorOfStructs<Test>(*test4) : 0, test4__,
testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0, testarrayofstring__,
testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(*testarrayoftables) : 0, testarrayoftables__,
enemy, enemy,
testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0, testnestedflatbuffer__,
testempty, testempty,
testbool, testbool,
testhashs32_fnv1, testhashs32_fnv1,
@ -1948,30 +1968,30 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
testhashu32_fnv1a, testhashu32_fnv1a,
testhashs64_fnv1a, testhashs64_fnv1a,
testhashu64_fnv1a, testhashu64_fnv1a,
testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0, testarrayofbools__,
testf, testf,
testf2, testf2,
testf3, testf3,
testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0, testarrayofstring2__,
testarrayofsortedstruct ? _fbb.CreateVectorOfStructs<Ability>(*testarrayofsortedstruct) : 0, testarrayofsortedstruct__,
flex ? _fbb.CreateVector<uint8_t>(*flex) : 0, flex__,
test5 ? _fbb.CreateVectorOfStructs<Test>(*test5) : 0, test5__,
vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0, vector_of_longs__,
vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0, vector_of_doubles__,
parent_namespace_test, parent_namespace_test,
vector_of_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_referrables) : 0, vector_of_referrables__,
single_weak_reference, single_weak_reference,
vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0, vector_of_weak_references__,
vector_of_strong_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_strong_referrables) : 0, vector_of_strong_referrables__,
co_owning_reference, co_owning_reference,
vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0, vector_of_co_owning_references__,
non_owning_reference, non_owning_reference,
vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0, vector_of_non_owning_references__,
any_unique_type, any_unique_type,
any_unique, any_unique,
any_ambiguous_type, any_ambiguous_type,
any_ambiguous, any_ambiguous,
vector_of_enums ? _fbb.CreateVector<int8_t>(*vector_of_enums) : 0); vector_of_enums__);
} }
flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
@ -2229,6 +2249,8 @@ inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
double f64 = 0.0, double f64 = 0.0,
const std::vector<int8_t> *v8 = nullptr, const std::vector<int8_t> *v8 = nullptr,
const std::vector<double> *vf64 = nullptr) { const std::vector<double> *vf64 = nullptr) {
auto v8__ = v8 ? _fbb.CreateVector<int8_t>(*v8) : 0;
auto vf64__ = vf64 ? _fbb.CreateVector<double>(*vf64) : 0;
return MyGame::Example::CreateTypeAliases( return MyGame::Example::CreateTypeAliases(
_fbb, _fbb,
i8, i8,
@ -2241,8 +2263,8 @@ inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
u64, u64,
f32, f32,
f64, f64,
v8 ? _fbb.CreateVector<int8_t>(*v8) : 0, v8__,
vf64 ? _fbb.CreateVector<double>(*vf64) : 0); vf64__);
} }
flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

View File

@ -429,12 +429,14 @@ inline flatbuffers::Offset<Movie> CreateMovieDirect(
flatbuffers::Offset<void> main_character = 0, flatbuffers::Offset<void> main_character = 0,
const std::vector<uint8_t> *characters_type = nullptr, const std::vector<uint8_t> *characters_type = nullptr,
const std::vector<flatbuffers::Offset<void>> *characters = nullptr) { const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
auto characters_type__ = characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0;
auto characters__ = characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0;
return CreateMovie( return CreateMovie(
_fbb, _fbb,
main_character_type, main_character_type,
main_character, main_character,
characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0, characters_type__,
characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0); characters__);
} }
flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);