Skip to content

Commit 148d925

Browse files
committed
add non scalar default bfbs support
1 parent 5218e29 commit 148d925

File tree

5 files changed

+45
-16
lines changed

5 files changed

+45
-16
lines changed

include/flatbuffers/idl.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,12 @@ struct Type {
226226
struct Value {
227227
Value()
228228
: constant("0"),
229+
has_non_scalar_constant(false),
229230
offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {}
230231
Type type;
231232
std::string constant;
233+
// not the most elegant solution, but much better than a full refactor.
234+
bool has_non_scalar_constant;
232235
voffset_t offset;
233236
};
234237

@@ -342,11 +345,9 @@ struct FieldDef : public Definition {
342345

343346
bool Deserialize(Parser &parser, const reflection::Field *field);
344347

345-
bool IsScalarOptional() const {
346-
return IsScalar() && IsOptional();
347-
}
348+
bool IsScalarOptional() const { return IsScalar() && IsOptional(); }
348349
bool IsScalar() const {
349-
return ::flatbuffers::IsScalar(value.type.base_type);
350+
return ::flatbuffers::IsScalar(value.type.base_type);
350351
}
351352
bool IsOptional() const { return presence == kOptional; }
352353
bool IsRequired() const { return presence == kRequired; }
@@ -710,7 +711,7 @@ struct IDLOptions {
710711
/********************************** Python **********************************/
711712
bool python_no_type_prefix_suffix;
712713
bool python_typing;
713-
bool python_decode_obj_api_strings=false;
714+
bool python_decode_obj_api_strings = false;
714715

715716
// The target Python version. Can be one of the following:
716717
// - "0"
@@ -1255,10 +1256,9 @@ class Parser : public ParserState {
12551256
// These functions return nullptr on success, or an error string,
12561257
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
12571258
// it contains non-UTF-8 byte arrays in String values).
1258-
extern bool GenerateTextFromTable(const Parser &parser,
1259-
const void *table,
1260-
const std::string &tablename,
1261-
std::string *text);
1259+
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
1260+
const std::string &tablename,
1261+
std::string *text);
12621262
extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
12631263
std::string *text);
12641264
extern const char *GenerateTextFile(const Parser &parser,

include/flatbuffers/reflection_generated.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct SchemaFileBuilder;
4545
struct Schema;
4646
struct SchemaBuilder;
4747

48-
enum BaseType {
48+
enum BaseType : int8_t {
4949
None = 0,
5050
UType = 1,
5151
Bool = 2,
@@ -128,7 +128,7 @@ inline const char *EnumNameBaseType(BaseType e) {
128128
}
129129

130130
/// New schema language features that are not supported by old code generators.
131-
enum AdvancedFeatures {
131+
enum AdvancedFeatures : uint64_t {
132132
AdvancedArrayFeatures = 1ULL,
133133
AdvancedUnionFeatures = 2ULL,
134134
OptionalScalars = 4ULL,
@@ -617,7 +617,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
617617
VT_DOCUMENTATION = 24,
618618
VT_OPTIONAL = 26,
619619
VT_PADDING = 28,
620-
VT_OFFSET64 = 30
620+
VT_OFFSET64 = 30,
621+
VT_DEFAULT_NON_SCALAR = 32
621622
};
622623
const ::flatbuffers::String *name() const {
623624
return GetPointer<const ::flatbuffers::String *>(VT_NAME);
@@ -675,6 +676,9 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
675676
bool offset64() const {
676677
return GetField<uint8_t>(VT_OFFSET64, 0) != 0;
677678
}
679+
const ::flatbuffers::String *default_non_scalar() const {
680+
return GetPointer<const ::flatbuffers::String *>(VT_DEFAULT_NON_SCALAR);
681+
}
678682
bool Verify(::flatbuffers::Verifier &verifier) const {
679683
return VerifyTableStart(verifier) &&
680684
VerifyOffsetRequired(verifier, VT_NAME) &&
@@ -697,6 +701,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
697701
VerifyField<uint8_t>(verifier, VT_OPTIONAL, 1) &&
698702
VerifyField<uint16_t>(verifier, VT_PADDING, 2) &&
699703
VerifyField<uint8_t>(verifier, VT_OFFSET64, 1) &&
704+
VerifyOffset(verifier, VT_DEFAULT_NON_SCALAR) &&
705+
verifier.VerifyString(default_non_scalar()) &&
700706
verifier.EndTable();
701707
}
702708
};
@@ -747,6 +753,9 @@ struct FieldBuilder {
747753
void add_offset64(bool offset64) {
748754
fbb_.AddElement<uint8_t>(Field::VT_OFFSET64, static_cast<uint8_t>(offset64), 0);
749755
}
756+
void add_default_non_scalar(::flatbuffers::Offset<::flatbuffers::String> default_non_scalar) {
757+
fbb_.AddOffset(Field::VT_DEFAULT_NON_SCALAR, default_non_scalar);
758+
}
750759
explicit FieldBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
751760
: fbb_(_fbb) {
752761
start_ = fbb_.StartTable();
@@ -775,10 +784,12 @@ inline ::flatbuffers::Offset<Field> CreateField(
775784
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> documentation = 0,
776785
bool optional = false,
777786
uint16_t padding = 0,
778-
bool offset64 = false) {
787+
bool offset64 = false,
788+
::flatbuffers::Offset<::flatbuffers::String> default_non_scalar = 0) {
779789
FieldBuilder builder_(_fbb);
780790
builder_.add_default_real(default_real);
781791
builder_.add_default_integer(default_integer);
792+
builder_.add_default_non_scalar(default_non_scalar);
782793
builder_.add_documentation(documentation);
783794
builder_.add_attributes(attributes);
784795
builder_.add_type(type);
@@ -809,10 +820,12 @@ inline ::flatbuffers::Offset<Field> CreateFieldDirect(
809820
const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *documentation = nullptr,
810821
bool optional = false,
811822
uint16_t padding = 0,
812-
bool offset64 = false) {
823+
bool offset64 = false,
824+
const char *default_non_scalar = nullptr) {
813825
auto name__ = name ? _fbb.CreateString(name) : 0;
814826
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
815827
auto documentation__ = documentation ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*documentation) : 0;
828+
auto default_non_scalar__ = default_non_scalar ? _fbb.CreateString(default_non_scalar) : 0;
816829
return reflection::CreateField(
817830
_fbb,
818831
name__,
@@ -828,7 +841,8 @@ inline ::flatbuffers::Offset<Field> CreateFieldDirect(
828841
documentation__,
829842
optional,
830843
padding,
831-
offset64);
844+
offset64,
845+
default_non_scalar__);
832846
}
833847

834848
struct Object FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {

reflection/reflection.fbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ table Field {
8888
padding:uint16 = 0;
8989
/// If the field uses 64-bit offsets.
9090
offset64:bool = false;
91+
default_non_scalar:string;
9192
}
9293

9394
table Object { // Used for both tables and structs.

src/binary_annotator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
418418
? std::to_string(field->default_real())
419419
: std::to_string(field->default_integer());
420420
default_label += "> (";
421+
} else if ((field->type()->base_type() == reflection::String ||
422+
field->type()->base_type() == reflection::Vector) &&
423+
field->default_non_scalar() != nullptr) {
424+
default_label += "<defaults to \"";
425+
default_label += field->default_non_scalar()->str();
426+
default_label += "\"> (";
421427
} else {
422428
default_label += "<null> (";
423429
}

src/idl_parser.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
994994
"Default values for strings and vectors are not supported in one "
995995
"of the specified programming languages");
996996
}
997+
field->value.has_non_scalar_constant = true;
997998
}
998999

9991000
if (IsVector(type) && field->value.constant != "0" &&
@@ -4042,6 +4043,8 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
40424043
auto docs__ = parser.opts.binary_schema_comments && !doc_comment.empty()
40434044
? builder->CreateVectorOfStrings(doc_comment)
40444045
: 0;
4046+
auto default_non_scalar__ =
4047+
value.has_non_scalar_constant ? builder->CreateString(value.constant) : 0;
40454048
double d;
40464049
StringToNumber(value.constant.c_str(), &d);
40474050
return reflection::CreateField(
@@ -4050,7 +4053,8 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
40504053
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
40514054
// result may be platform-dependent if underlying is float (not double)
40524055
IsFloat(value.type.base_type) ? d : 0.0, deprecated, IsRequired(), key,
4053-
attr__, docs__, IsOptional(), static_cast<uint16_t>(padding), offset64);
4056+
attr__, docs__, IsOptional(), static_cast<uint16_t>(padding), offset64,
4057+
default_non_scalar__);
40544058
// TODO: value.constant is almost always "0", we could save quite a bit of
40554059
// space by sharing it. Same for common values of value.type.
40564060
}
@@ -4064,6 +4068,10 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
40644068
value.constant = NumToString(field->default_integer());
40654069
} else if (IsFloat(value.type.base_type)) {
40664070
value.constant = FloatToString(field->default_real(), 17);
4071+
} else if (IsString(value.type) || IsVector(value.type)) {
4072+
value.constant =
4073+
field->default_non_scalar() ? field->default_non_scalar()->str() : "";
4074+
value.has_non_scalar_constant = true;
40674075
}
40684076
presence = FieldDef::MakeFieldPresence(field->optional(), field->required());
40694077
padding = field->padding();

0 commit comments

Comments
 (0)