Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
flatbuffers
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
flatbuffers
Commits
a9194c4c
Commit
a9194c4c
authored
Jun 02, 2016
by
lakedaemon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cpp generator : pulling all methods inside the class
parent
ca32eb77
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
370 additions
and
384 deletions
+370
-384
idl_gen_cpp.cpp
src/idl_gen_cpp.cpp
+368
-382
monster_test_generated.h
tests/monster_test_generated.h
+2
-2
No files found.
src/idl_gen_cpp.cpp
View file @
a9194c4c
...
@@ -22,72 +22,247 @@
...
@@ -22,72 +22,247 @@
#include "flatbuffers/code_generators.h"
#include "flatbuffers/code_generators.h"
namespace
flatbuffers
{
namespace
flatbuffers
{
struct
IsAlnum
{
bool
operator
()(
char
c
)
{
return
!
isalnum
(
c
);
}
};
static
std
::
string
GeneratedFileName
(
const
std
::
string
&
path
,
const
std
::
string
&
file_name
)
{
return
path
+
file_name
+
"_generated.h"
;
}
namespace
cpp
{
namespace
cpp
{
class
CppGenerator
:
public
BaseGenerator
{
public
:
CppGenerator
(
const
Parser
&
parser
,
const
std
::
string
&
path
,
const
std
::
string
&
file_name
)
:
BaseGenerator
(
parser
,
path
,
file_name
){};
// Iterate through all definitions we haven't generate code for (enums,
// structs,
// and tables) and output them to a single file.
bool
generate
()
{
if
(
IsEverythingGenerated
())
return
true
;
std
::
string
code
;
code
=
code
+
"// "
+
FlatBuffersGeneratedWarning
();
// Generate include guard.
std
::
string
include_guard_ident
=
file_name_
;
// Remove any non-alpha-numeric characters that may appear in a filename.
include_guard_ident
.
erase
(
std
::
remove_if
(
include_guard_ident
.
begin
(),
include_guard_ident
.
end
(),
IsAlnum
()),
include_guard_ident
.
end
());
std
::
string
include_guard
=
"FLATBUFFERS_GENERATED_"
+
include_guard_ident
;
include_guard
+=
"_"
;
// For further uniqueness, also add the namespace.
auto
name_space
=
parser_
.
namespaces_
.
back
();
for
(
auto
it
=
name_space
->
components
.
begin
();
it
!=
name_space
->
components
.
end
();
++
it
)
{
include_guard
+=
*
it
+
"_"
;
}
include_guard
+=
"H_"
;
std
::
transform
(
include_guard
.
begin
(),
include_guard
.
end
(),
include_guard
.
begin
(),
::
toupper
);
code
+=
"#ifndef "
+
include_guard
+
"
\n
"
;
code
+=
"#define "
+
include_guard
+
"
\n\n
"
;
code
+=
"#include
\"
flatbuffers/flatbuffers.h
\"\n\n
"
;
if
(
parser_
.
opts
.
include_dependence_headers
)
{
int
num_includes
=
0
;
for
(
auto
it
=
parser_
.
included_files_
.
begin
();
it
!=
parser_
.
included_files_
.
end
();
++
it
)
{
auto
basename
=
flatbuffers
::
StripPath
(
flatbuffers
::
StripExtension
(
it
->
first
));
if
(
basename
!=
file_name_
)
{
code
+=
"#include
\"
"
+
basename
+
"_generated.h
\"\n
"
;
num_includes
++
;
}
}
if
(
num_includes
)
code
+=
"
\n
"
;
}
assert
(
!
code_generator_cur_name_space
);
// Generate forward declarations for all structs/tables, since they may
// have circular references.
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
code
+=
"struct "
+
struct_def
.
name
+
";
\n\n
"
;
}
}
// Generate code for all the enum declarations.
for
(
auto
it
=
parser_
.
enums_
.
vec
.
begin
();
it
!=
parser_
.
enums_
.
vec
.
end
();
++
it
)
{
auto
&
enum_def
=
**
it
;
if
(
!
enum_def
.
generated
)
{
CheckNameSpace
(
**
it
,
&
code
);
GenEnum
(
**
it
,
&
code
);
}
}
// This tracks the current namespace so we can insert namespace declarations.
// Generate code for all structs, then all tables.
// TODO(wvo): this needs to be moved into a code generator context object.
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
static
const
Namespace
*
code_generator_cur_name_space
=
nullptr
;
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
struct_def
.
fixed
&&
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
GenStruct
(
struct_def
,
&
code
);
}
}
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
!
struct_def
.
fixed
&&
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
GenTable
(
struct_def
,
&
code
);
}
}
// Ensure that a type is prefixed with its namespace whenever it is used
// Generate code for union verifiers.
// outside of its namespace.
for
(
auto
it
=
parser_
.
enums_
.
vec
.
begin
();
it
!=
parser_
.
enums_
.
vec
.
end
();
static
std
::
string
WrapInNameSpace
(
const
Namespace
*
ns
,
++
it
)
{
const
std
::
string
&
name
)
{
auto
&
enum_def
=
**
it
;
if
(
enum_def
.
is_union
&&
!
enum_def
.
generated
)
{
CheckNameSpace
(
enum_def
,
&
code
);
GenEnumPost
(
enum_def
,
&
code
);
}
}
// Generate convenient global helper functions:
if
(
parser_
.
root_struct_def_
)
{
CheckNameSpace
(
*
parser_
.
root_struct_def_
,
&
code
);
auto
&
name
=
parser_
.
root_struct_def_
->
name
;
std
::
string
qualified_name
=
parser_
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
name
);
std
::
string
cpp_qualified_name
=
TranslateNameSpace
(
qualified_name
);
// The root datatype accessor:
code
+=
"inline const "
+
cpp_qualified_name
+
" *Get"
;
code
+=
name
;
code
+=
"(const void *buf) { return flatbuffers::GetRoot<"
;
code
+=
cpp_qualified_name
+
">(buf); }
\n\n
"
;
if
(
parser_
.
opts
.
mutable_buffer
)
{
code
+=
"inline "
+
name
+
" *GetMutable"
;
code
+=
name
;
code
+=
"(void *buf) { return flatbuffers::GetMutableRoot<"
;
code
+=
name
+
">(buf); }
\n\n
"
;
}
// The root verifier:
code
+=
"inline bool Verify"
;
code
+=
name
;
code
+=
"Buffer(flatbuffers::Verifier &verifier) { "
"return verifier.VerifyBuffer<"
;
code
+=
cpp_qualified_name
+
">(); }
\n\n
"
;
if
(
parser_
.
file_identifier_
.
length
())
{
// Return the identifier
code
+=
"inline const char *"
+
name
;
code
+=
"Identifier() { return
\"
"
+
parser_
.
file_identifier_
;
code
+=
"
\"
; }
\n\n
"
;
// Check if a buffer has the identifier.
code
+=
"inline bool "
+
name
;
code
+=
"BufferHasIdentifier(const void *buf) { return flatbuffers::"
;
code
+=
"BufferHasIdentifier(buf, "
;
code
+=
name
+
"Identifier()); }
\n\n
"
;
}
if
(
parser_
.
file_extension_
.
length
())
{
// Return the extension
code
+=
"inline const char *"
+
name
;
code
+=
"Extension() { return
\"
"
+
parser_
.
file_extension_
;
code
+=
"
\"
; }
\n\n
"
;
}
// Finish a buffer with a given root object:
code
+=
"inline void Finish"
+
name
;
code
+=
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<"
;
code
+=
cpp_qualified_name
+
"> root) { fbb.Finish(root"
;
if
(
parser_
.
file_identifier_
.
length
())
code
+=
", "
+
name
+
"Identifier()"
;
code
+=
"); }
\n\n
"
;
}
assert
(
code_generator_cur_name_space
);
CloseNestedNameSpaces
(
code_generator_cur_name_space
,
&
code
);
code_generator_cur_name_space
=
nullptr
;
// Close the include guard.
code
+=
"
\n
#endif // "
+
include_guard
+
"
\n
"
;
return
SaveFile
(
GeneratedFileName
(
path_
,
file_name_
).
c_str
(),
code
,
false
);
}
private
:
// This tracks the current namespace so we can insert namespace declarations.
const
Namespace
*
code_generator_cur_name_space
=
nullptr
;
// Ensure that a type is prefixed with its namespace whenever it is used
// outside of its namespace.
std
::
string
WrapInNameSpace
(
const
Namespace
*
ns
,
const
std
::
string
&
name
)
{
if
(
code_generator_cur_name_space
!=
ns
)
{
if
(
code_generator_cur_name_space
!=
ns
)
{
std
::
string
qualified_name
;
std
::
string
qualified_name
;
for
(
auto
it
=
ns
->
components
.
begin
();
for
(
auto
it
=
ns
->
components
.
begin
();
it
!=
ns
->
components
.
end
();
++
it
)
{
it
!=
ns
->
components
.
end
();
++
it
)
{
qualified_name
+=
*
it
+
"::"
;
qualified_name
+=
*
it
+
"::"
;
}
}
return
qualified_name
+
name
;
return
qualified_name
+
name
;
}
else
{
}
else
{
return
name
;
return
name
;
}
}
}
}
static
std
::
string
WrapInNameSpace
(
const
Definition
&
def
)
{
std
::
string
WrapInNameSpace
(
const
Definition
&
def
)
{
return
WrapInNameSpace
(
def
.
defined_namespace
,
def
.
name
);
return
WrapInNameSpace
(
def
.
defined_namespace
,
def
.
name
);
}
}
// Translates a qualified name in flatbuffer text format to the same name in
// Translates a qualified name in flatbuffer text format to the same name in
// the equivalent C++ namespace.
// the equivalent C++ namespace.
static
std
::
string
TranslateNameSpace
(
const
std
::
string
&
qualified_name
)
{
static
std
::
string
TranslateNameSpace
(
const
std
::
string
&
qualified_name
)
{
std
::
string
cpp_qualified_name
=
qualified_name
;
std
::
string
cpp_qualified_name
=
qualified_name
;
size_t
start_pos
=
0
;
size_t
start_pos
=
0
;
while
((
start_pos
=
cpp_qualified_name
.
find
(
"."
,
start_pos
))
!=
while
((
start_pos
=
cpp_qualified_name
.
find
(
"."
,
start_pos
))
!=
std
::
string
::
npos
)
{
std
::
string
::
npos
)
{
cpp_qualified_name
.
replace
(
start_pos
,
1
,
"::"
);
cpp_qualified_name
.
replace
(
start_pos
,
1
,
"::"
);
}
}
return
cpp_qualified_name
;
return
cpp_qualified_name
;
}
}
// Return a C++ type from the table in idl.h
// Return a C++ type from the table in idl.h
static
std
::
string
GenTypeBasic
(
const
Type
&
type
,
bool
user_facing_type
)
{
std
::
string
GenTypeBasic
(
const
Type
&
type
,
bool
user_facing_type
)
{
static
const
char
*
ctypename
[]
=
{
static
const
char
*
ctypename
[]
=
{
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) #CTYPE,
#CTYPE,
FLATBUFFERS_GEN_TYPES
(
FLATBUFFERS_TD
)
FLATBUFFERS_GEN_TYPES
(
FLATBUFFERS_TD
)
#undef FLATBUFFERS_TD
#undef FLATBUFFERS_TD
};
};
if
(
user_facing_type
)
{
if
(
user_facing_type
)
{
if
(
type
.
enum_def
)
return
WrapInNameSpace
(
*
type
.
enum_def
);
if
(
type
.
enum_def
)
return
WrapInNameSpace
(
*
type
.
enum_def
);
if
(
type
.
base_type
==
BASE_TYPE_BOOL
)
return
"bool"
;
if
(
type
.
base_type
==
BASE_TYPE_BOOL
)
return
"bool"
;
}
}
return
ctypename
[
type
.
base_type
];
return
ctypename
[
type
.
base_type
];
}
}
static
std
::
string
GenTypeWire
(
const
Parser
&
parser
,
const
Type
&
type
,
const
char
*
postfix
,
bool
user_facing_type
);
// Return a C++ pointer type, specialized to the actual struct/table types,
// Return a C++ pointer type, specialized to the actual struct/table types,
// and vector element types.
// and vector element types.
static
std
::
string
GenTypePointer
(
const
Parser
&
parser
,
const
Type
&
type
)
{
std
::
string
GenTypePointer
(
const
Type
&
type
)
{
switch
(
type
.
base_type
)
{
switch
(
type
.
base_type
)
{
case
BASE_TYPE_STRING
:
case
BASE_TYPE_STRING
:
return
"flatbuffers::String"
;
return
"flatbuffers::String"
;
case
BASE_TYPE_VECTOR
:
case
BASE_TYPE_VECTOR
:
return
"flatbuffers::Vector<"
+
return
"flatbuffers::Vector<"
+
GenTypeWire
(
parser
,
type
.
VectorType
(),
""
,
false
)
+
">"
;
GenTypeWire
(
type
.
VectorType
(),
""
,
false
)
+
">"
;
case
BASE_TYPE_STRUCT
:
{
case
BASE_TYPE_STRUCT
:
{
return
WrapInNameSpace
(
*
type
.
struct_def
);
return
WrapInNameSpace
(
*
type
.
struct_def
);
}
}
...
@@ -96,51 +271,52 @@ static std::string GenTypePointer(const Parser &parser, const Type &type) {
...
@@ -96,51 +271,52 @@ static std::string GenTypePointer(const Parser &parser, const Type &type) {
default
:
default
:
return
"void"
;
return
"void"
;
}
}
}
}
// Return a C++ type for any type (scalar/pointer) specifically for
// Return a C++ type for any type (scalar/pointer) specifically for
// building a flatbuffer.
// building a flatbuffer.
static
std
::
string
GenTypeWire
(
const
Parser
&
parser
,
const
Type
&
type
,
std
::
string
GenTypeWire
(
const
Type
&
type
,
const
char
*
postfix
,
bool
user_facing_type
)
{
const
char
*
postfix
,
bool
user_facing_type
)
{
return
IsScalar
(
type
.
base_type
)
return
IsScalar
(
type
.
base_type
)
?
GenTypeBasic
(
type
,
user_facing_type
)
+
postfix
?
GenTypeBasic
(
type
,
user_facing_type
)
+
postfix
:
IsStruct
(
type
)
:
IsStruct
(
type
)
?
"const "
+
GenTypePointer
(
parser
,
type
)
+
" *"
?
"const "
+
GenTypePointer
(
type
)
+
" *"
:
"flatbuffers::Offset<"
+
GenTypePointer
(
parser
,
type
)
+
">"
+
postfix
;
:
"flatbuffers::Offset<"
+
GenTypePointer
(
type
)
+
}
">"
+
postfix
;
}
// Return a C++ type for any type (scalar/pointer) that reflects its
// Return a C++ type for any type (scalar/pointer) that reflects its
// serialized size.
// serialized size.
static
std
::
string
GenTypeSize
(
const
Parser
&
parser
,
const
Type
&
type
)
{
std
::
string
GenTypeSize
(
const
Type
&
type
)
{
return
IsScalar
(
type
.
base_type
)
return
IsScalar
(
type
.
base_type
)
?
GenTypeBasic
(
type
,
false
)
?
GenTypeBasic
(
type
,
false
)
:
IsStruct
(
type
)
:
IsStruct
(
type
)
?
GenTypePointer
(
type
)
?
GenTypePointer
(
parser
,
type
)
:
"flatbuffers::uoffset_t"
;
:
"flatbuffers::uoffset_t"
;
}
}
// Return a C++ type for any type (scalar/pointer) specifically for
// Return a C++ type for any type (scalar/pointer) specifically for
// using a flatbuffer.
// using a flatbuffer.
static
std
::
string
GenTypeGet
(
const
Parser
&
parser
,
const
Type
&
type
,
std
::
string
GenTypeGet
(
const
Type
&
type
,
const
char
*
afterbasic
,
const
char
*
beforeptr
,
const
char
*
afterbasic
,
const
char
*
beforeptr
,
const
char
*
afterptr
,
bool
user_facing_type
)
{
const
char
*
afterptr
,
bool
user_facing_type
)
{
return
IsScalar
(
type
.
base_type
)
return
IsScalar
(
type
.
base_type
)
?
GenTypeBasic
(
type
,
user_facing_type
)
+
afterbasic
?
GenTypeBasic
(
type
,
user_facing_type
)
+
afterbasic
:
beforeptr
+
GenTypePointer
(
parser
,
type
)
+
afterptr
;
:
beforeptr
+
GenTypePointer
(
type
)
+
afterptr
;
}
}
static
std
::
string
GenEnumDecl
(
const
EnumDef
&
enum_def
,
static
std
::
string
GenEnumDecl
(
const
EnumDef
&
enum_def
,
const
IDLOptions
&
opts
)
{
const
IDLOptions
&
opts
)
{
return
(
opts
.
scoped_enums
?
"enum class "
:
"enum "
)
+
enum_def
.
name
;
return
(
opts
.
scoped_enums
?
"enum class "
:
"enum "
)
+
enum_def
.
name
;
}
}
static
std
::
string
GenEnumVal
(
const
EnumDef
&
enum_def
,
static
std
::
string
GenEnumVal
(
const
EnumDef
&
enum_def
,
const
std
::
string
&
enum_val
,
const
std
::
string
&
enum_val
,
const
IDLOptions
&
opts
)
{
const
IDLOptions
&
opts
)
{
return
opts
.
prefixed_enums
?
enum_def
.
name
+
"_"
+
enum_val
:
enum_val
;
return
opts
.
prefixed_enums
?
enum_def
.
name
+
"_"
+
enum_val
:
enum_val
;
}
}
static
std
::
string
GetEnumVal
(
const
EnumDef
&
enum_def
,
const
EnumVal
&
enum_val
,
static
std
::
string
GetEnumVal
(
const
EnumDef
&
enum_def
,
const
EnumVal
&
enum_val
,
const
IDLOptions
&
opts
)
{
const
IDLOptions
&
opts
)
{
if
(
opts
.
scoped_enums
)
{
if
(
opts
.
scoped_enums
)
{
return
enum_def
.
name
+
"::"
+
enum_val
.
name
;
return
enum_def
.
name
+
"::"
+
enum_val
.
name
;
...
@@ -149,70 +325,70 @@ static std::string GetEnumVal(const EnumDef &enum_def, const EnumVal &enum_val,
...
@@ -149,70 +325,70 @@ static std::string GetEnumVal(const EnumDef &enum_def, const EnumVal &enum_val,
}
else
{
}
else
{
return
enum_val
.
name
;
return
enum_val
.
name
;
}
}
}
}
std
::
string
EnumSignature
(
EnumDef
&
enum_def
)
{
std
::
string
EnumSignature
(
EnumDef
&
enum_def
)
{
return
"inline bool Verify"
+
enum_def
.
name
+
return
"inline bool Verify"
+
enum_def
.
name
+
"(flatbuffers::Verifier &verifier
, "
+
"(flatbuffers::Verifier &verifier, "
+
"const void *union_obj
, "
+
"const void *union_obj, "
+
enum_def
.
name
+
" type)"
;
enum_def
.
name
+
" type)"
;
}
}
// Generate an enum declaration and an enum string lookup table.
// Generate an enum declaration and an enum string lookup table.
static
void
GenEnum
(
const
Parser
&
parser
,
EnumDef
&
enum_def
,
void
GenEnum
(
EnumDef
&
enum_def
,
std
::
string
*
code_ptr
)
{
std
::
string
*
code_ptr
)
{
std
::
string
&
code
=
*
code_ptr
;
std
::
string
&
code
=
*
code_ptr
;
GenComment
(
enum_def
.
doc_comment
,
code_ptr
,
nullptr
);
GenComment
(
enum_def
.
doc_comment
,
code_ptr
,
nullptr
);
code
+=
GenEnumDecl
(
enum_def
,
parser
.
opts
);
code
+=
GenEnumDecl
(
enum_def
,
parser_
.
opts
);
if
(
parser
.
opts
.
scoped_enums
)
if
(
parser_
.
opts
.
scoped_enums
)
code
+=
" : "
+
GenTypeBasic
(
enum_def
.
underlying_type
,
false
);
code
+=
" : "
+
GenTypeBasic
(
enum_def
.
underlying_type
,
false
);
code
+=
" {
\n
"
;
code
+=
" {
\n
"
;
int64_t
anyv
=
0
;
int64_t
anyv
=
0
;
EnumVal
*
minv
=
nullptr
,
*
maxv
=
nullptr
;
EnumVal
*
minv
=
nullptr
,
*
maxv
=
nullptr
;
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
it
!=
enum_def
.
vals
.
vec
.
end
();
it
!=
enum_def
.
vals
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
ev
=
**
it
;
auto
&
ev
=
**
it
;
GenComment
(
ev
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
GenComment
(
ev
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
code
+=
" "
+
GenEnumVal
(
enum_def
,
ev
.
name
,
parser
.
opts
)
+
" = "
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
ev
.
name
,
parser_
.
opts
)
+
" = "
;
code
+=
NumToString
(
ev
.
value
)
+
",
\n
"
;
code
+=
NumToString
(
ev
.
value
)
+
",
\n
"
;
minv
=
!
minv
||
minv
->
value
>
ev
.
value
?
&
ev
:
minv
;
minv
=
!
minv
||
minv
->
value
>
ev
.
value
?
&
ev
:
minv
;
maxv
=
!
maxv
||
maxv
->
value
<
ev
.
value
?
&
ev
:
maxv
;
maxv
=
!
maxv
||
maxv
->
value
<
ev
.
value
?
&
ev
:
maxv
;
anyv
|=
ev
.
value
;
anyv
|=
ev
.
value
;
}
}
if
(
parser
.
opts
.
scoped_enums
||
parser
.
opts
.
prefixed_enums
)
{
if
(
parser_
.
opts
.
scoped_enums
||
parser_
.
opts
.
prefixed_enums
)
{
assert
(
minv
&&
maxv
);
assert
(
minv
&&
maxv
);
if
(
enum_def
.
attributes
.
Lookup
(
"bit_flags"
))
{
if
(
enum_def
.
attributes
.
Lookup
(
"bit_flags"
))
{
if
(
minv
->
value
!=
0
)
// If the user didn't defined NONE value
if
(
minv
->
value
!=
0
)
// If the user didn't defined NONE value
code
+=
" "
+
GenEnumVal
(
enum_def
,
"NONE"
,
parser
.
opts
)
+
" = 0,
\n
"
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
"NONE"
,
parser_
.
opts
)
+
" = 0,
\n
"
;
if
(
maxv
->
value
!=
anyv
)
// If the user didn't defined ANY value
if
(
maxv
->
value
!=
anyv
)
// If the user didn't defined ANY value
code
+=
" "
+
GenEnumVal
(
enum_def
,
"ANY"
,
parser
.
opts
)
+
" = "
+
NumToString
(
anyv
)
+
"
\n
"
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
"ANY"
,
parser_
.
opts
)
+
" = "
+
NumToString
(
anyv
)
+
"
\n
"
;
}
else
{
// MIN & MAX are useless for bit_flags
}
else
{
// MIN & MAX are useless for bit_flags
code
+=
" "
+
GenEnumVal
(
enum_def
,
"MIN"
,
parser
.
opts
)
+
" = "
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
"MIN"
,
parser_
.
opts
)
+
" = "
;
code
+=
GenEnumVal
(
enum_def
,
minv
->
name
,
parser
.
opts
)
+
",
\n
"
;
code
+=
GenEnumVal
(
enum_def
,
minv
->
name
,
parser_
.
opts
)
+
",
\n
"
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
"MAX"
,
parser
.
opts
)
+
" = "
;
code
+=
" "
+
GenEnumVal
(
enum_def
,
"MAX"
,
parser_
.
opts
)
+
" = "
;
code
+=
GenEnumVal
(
enum_def
,
maxv
->
name
,
parser
.
opts
)
+
"
\n
"
;
code
+=
GenEnumVal
(
enum_def
,
maxv
->
name
,
parser_
.
opts
)
+
"
\n
"
;
}
}
}
}
code
+=
"};
\n
"
;
code
+=
"};
\n
"
;
if
(
parser
.
opts
.
scoped_enums
&&
enum_def
.
attributes
.
Lookup
(
"bit_flags"
))
if
(
parser_
.
opts
.
scoped_enums
&&
enum_def
.
attributes
.
Lookup
(
"bit_flags"
))
code
+=
"DEFINE_BITMASK_OPERATORS("
+
enum_def
.
name
+
", "
+
GenTypeBasic
(
enum_def
.
underlying_type
,
false
)
+
")
\n
"
;
code
+=
"DEFINE_BITMASK_OPERATORS("
+
enum_def
.
name
+
", "
+
GenTypeBasic
(
enum_def
.
underlying_type
,
false
)
+
")
\n
"
;
code
+=
"
\n
"
;
code
+=
"
\n
"
;
// Generate a generate string table for enum values.
// Generate a generate string table for enum values.
// Problem is, if values are very sparse that could generate really big
// Problem is, if values are very sparse that could generate really big
// tables. Ideally in that case we generate a map lookup instead, but for
// tables. Ideally in that case we generate a map lookup instead, but for
// the moment we simply don't output a table at all.
// the moment we simply don't output a table at all.
auto
range
=
enum_def
.
vals
.
vec
.
back
()
->
value
-
auto
range
=
enum_def
.
vals
.
vec
.
front
()
->
value
+
1
;
enum_def
.
vals
.
vec
.
back
()
->
value
-
enum_def
.
vals
.
vec
.
front
()
->
value
+
1
;
// Average distance between values above which we consider a table
// Average distance between values above which we consider a table
// "too sparse". Change at will.
// "too sparse". Change at will.
static
const
int
kMaxSparseness
=
5
;
static
const
int
kMaxSparseness
=
5
;
if
(
range
/
static_cast
<
int64_t
>
(
enum_def
.
vals
.
vec
.
size
())
<
kMaxSparseness
)
{
if
(
range
/
static_cast
<
int64_t
>
(
enum_def
.
vals
.
vec
.
size
())
<
kMaxSparseness
)
{
code
+=
"inline const char **EnumNames"
+
enum_def
.
name
+
"() {
\n
"
;
code
+=
"inline const char **EnumNames"
+
enum_def
.
name
+
"() {
\n
"
;
code
+=
" static const char *names[] = { "
;
code
+=
" static const char *names[] = { "
;
auto
val
=
enum_def
.
vals
.
vec
.
front
()
->
value
;
auto
val
=
enum_def
.
vals
.
vec
.
front
()
->
value
;
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
it
!=
enum_def
.
vals
.
vec
.
end
();
it
!=
enum_def
.
vals
.
vec
.
end
();
++
it
)
{
++
it
)
{
while
(
val
++
!=
(
*
it
)
->
value
)
code
+=
"
\"\"
, "
;
while
(
val
++
!=
(
*
it
)
->
value
)
code
+=
"
\"\"
, "
;
code
+=
"
\"
"
+
(
*
it
)
->
name
+
"
\"
, "
;
code
+=
"
\"
"
+
(
*
it
)
->
name
+
"
\"
, "
;
...
@@ -223,7 +399,8 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
...
@@ -223,7 +399,8 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
code
+=
"()[static_cast<int>(e)"
;
code
+=
"()[static_cast<int>(e)"
;
if
(
enum_def
.
vals
.
vec
.
front
()
->
value
)
{
if
(
enum_def
.
vals
.
vec
.
front
()
->
value
)
{
code
+=
" - static_cast<int>("
;
code
+=
" - static_cast<int>("
;
code
+=
GetEnumVal
(
enum_def
,
*
enum_def
.
vals
.
vec
.
front
(),
parser
.
opts
)
+
")"
;
code
+=
GetEnumVal
(
enum_def
,
*
enum_def
.
vals
.
vec
.
front
(),
parser_
.
opts
)
+
")"
;
}
}
code
+=
"]; }
\n\n
"
;
code
+=
"]; }
\n\n
"
;
}
}
...
@@ -231,10 +408,9 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
...
@@ -231,10 +408,9 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
if
(
enum_def
.
is_union
)
{
if
(
enum_def
.
is_union
)
{
code
+=
EnumSignature
(
enum_def
)
+
";
\n\n
"
;
code
+=
EnumSignature
(
enum_def
)
+
";
\n\n
"
;
}
}
}
}
static
void
GenEnumPost
(
const
Parser
&
parser
,
EnumDef
&
enum_def
,
void
GenEnumPost
(
EnumDef
&
enum_def
,
std
::
string
*
code_ptr_post
)
{
std
::
string
*
code_ptr_post
)
{
// Generate a verifier function for this union that can be called by the
// Generate a verifier function for this union that can be called by the
// table verifier functions. It uses a switch case to select a specific
// table verifier functions. It uses a switch case to select a specific
// verifier function to call, this should be safe even if the union type
// verifier function to call, this should be safe even if the union type
...
@@ -242,11 +418,10 @@ static void GenEnumPost(const Parser &parser, EnumDef &enum_def,
...
@@ -242,11 +418,10 @@ static void GenEnumPost(const Parser &parser, EnumDef &enum_def,
// on the wrong type.
// on the wrong type.
std
::
string
&
code_post
=
*
code_ptr_post
;
std
::
string
&
code_post
=
*
code_ptr_post
;
code_post
+=
EnumSignature
(
enum_def
)
+
" {
\n
switch (type) {
\n
"
;
code_post
+=
EnumSignature
(
enum_def
)
+
" {
\n
switch (type) {
\n
"
;
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
for
(
auto
it
=
enum_def
.
vals
.
vec
.
begin
();
it
!=
enum_def
.
vals
.
vec
.
end
();
it
!=
enum_def
.
vals
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
ev
=
**
it
;
auto
&
ev
=
**
it
;
code_post
+=
" case "
+
GetEnumVal
(
enum_def
,
ev
,
parser
.
opts
);
code_post
+=
" case "
+
GetEnumVal
(
enum_def
,
ev
,
parser_
.
opts
);
if
(
!
ev
.
value
)
{
if
(
!
ev
.
value
)
{
code_post
+=
": return true;
\n
"
;
// "NONE" enum value.
code_post
+=
": return true;
\n
"
;
// "NONE" enum value.
}
else
{
}
else
{
...
@@ -256,49 +431,52 @@ static void GenEnumPost(const Parser &parser, EnumDef &enum_def,
...
@@ -256,49 +431,52 @@ static void GenEnumPost(const Parser &parser, EnumDef &enum_def,
}
}
}
}
code_post
+=
" default: return false;
\n
}
\n
}
\n\n
"
;
code_post
+=
" default: return false;
\n
}
\n
}
\n\n
"
;
}
}
// Generates a value with optionally a cast applied if the field has a
// Generates a value with optionally a cast applied if the field has a
// different underlying type from its interface type (currently only the
// different underlying type from its interface type (currently only the
// case for enums. "from" specify the direction, true meaning from the
// case for enums. "from" specify the direction, true meaning from the
// underlying type to the interface type.
// underlying type to the interface type.
std
::
string
GenUnderlyingCast
(
const
FieldDef
&
field
,
bool
from
,
std
::
string
GenUnderlyingCast
(
const
FieldDef
&
field
,
bool
from
,
const
std
::
string
&
val
)
{
const
std
::
string
&
val
)
{
if
(
from
&&
field
.
value
.
type
.
base_type
==
BASE_TYPE_BOOL
)
{
if
(
from
&&
field
.
value
.
type
.
base_type
==
BASE_TYPE_BOOL
)
{
return
val
+
" != 0"
;
return
val
+
" != 0"
;
}
else
if
((
field
.
value
.
type
.
enum_def
&&
}
else
if
((
field
.
value
.
type
.
enum_def
&&
IsScalar
(
field
.
value
.
type
.
base_type
))
||
IsScalar
(
field
.
value
.
type
.
base_type
))
||
field
.
value
.
type
.
base_type
==
BASE_TYPE_BOOL
)
{
field
.
value
.
type
.
base_type
==
BASE_TYPE_BOOL
)
{
return
"static_cast<"
+
GenTypeBasic
(
field
.
value
.
type
,
from
)
+
return
"static_cast<"
+
GenTypeBasic
(
field
.
value
.
type
,
from
)
+
">("
+
">("
+
val
+
")"
;
val
+
")"
;
}
else
{
}
else
{
return
val
;
return
val
;
}
}
}
}
std
::
string
GenFieldOffsetName
(
const
FieldDef
&
field
)
{
std
::
string
GenFieldOffsetName
(
const
FieldDef
&
field
)
{
std
::
string
uname
=
field
.
name
;
std
::
string
uname
=
field
.
name
;
std
::
transform
(
uname
.
begin
(),
uname
.
end
(),
uname
.
begin
(),
::
toupper
);
std
::
transform
(
uname
.
begin
(),
uname
.
end
(),
uname
.
begin
(),
::
toupper
);
return
"VT_"
+
uname
;
return
"VT_"
+
uname
;
}
}
static
void
GenFullyQualifiedNameGetter
(
const
Parser
&
parser
,
const
std
::
string
&
name
,
std
::
string
&
code
)
{
void
GenFullyQualifiedNameGetter
(
const
std
::
string
&
name
,
if
(
parser
.
opts
.
generate_name_strings
)
{
std
::
string
&
code
)
{
code
+=
" static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() {
\n
"
;
if
(
parser_
.
opts
.
generate_name_strings
)
{
code
+=
" return
\"
"
+
parser
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
name
)
+
"
\"
;
\n
"
;
code
+=
" static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() "
"{
\n
"
;
code
+=
" return
\"
"
+
parser_
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
name
)
+
"
\"
;
\n
"
;
code
+=
" }
\n
"
;
code
+=
" }
\n
"
;
}
}
}
}
std
::
string
GenDefaultConstant
(
const
FieldDef
&
field
)
{
std
::
string
GenDefaultConstant
(
const
FieldDef
&
field
)
{
return
field
.
value
.
type
.
base_type
==
BASE_TYPE_FLOAT
return
field
.
value
.
type
.
base_type
==
BASE_TYPE_FLOAT
?
field
.
value
.
constant
+
"f"
?
field
.
value
.
constant
+
"f"
:
field
.
value
.
constant
;
:
field
.
value
.
constant
;
}
}
// Generate an accessor struct, builder structs & function for a table.
// Generate an accessor struct, builder structs & function for a table.
static
void
GenTable
(
const
Parser
&
parser
,
StructDef
&
struct_def
,
void
GenTable
(
StructDef
&
struct_def
,
std
::
string
*
code_ptr
)
{
std
::
string
*
code_ptr
)
{
std
::
string
&
code
=
*
code_ptr
;
std
::
string
&
code
=
*
code_ptr
;
// Generate an accessor struct, with methods of the form:
// Generate an accessor struct, with methods of the form:
// type name() const { return GetField<type>(offset, defaultval); }
// type name() const { return GetField<type>(offset, defaultval); }
...
@@ -307,18 +485,19 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -307,18 +485,19 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
" FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table"
;
code
+=
" FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table"
;
code
+=
" {
\n
"
;
code
+=
" {
\n
"
;
// Generate GetFullyQualifiedName
// Generate GetFullyQualifiedName
GenFullyQualifiedNameGetter
(
parser
,
struct_def
.
name
,
code
);
GenFullyQualifiedNameGetter
(
struct_def
.
name
,
code
);
// Generate field id constants.
// Generate field id constants.
if
(
struct_def
.
fields
.
vec
.
size
()
>
0
)
{
if
(
struct_def
.
fields
.
vec
.
size
()
>
0
)
{
code
+=
" enum {
\n
"
;
code
+=
" enum {
\n
"
;
bool
is_first_field
=
true
;
// track the first field that's not deprecated
bool
is_first_field
=
true
;
// track the first field that's not deprecated
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
// Deprecated fields won't be accessible.
if
(
!
field
.
deprecated
)
{
// Deprecated fields won't be accessible.
if
(
!
is_first_field
)
{
if
(
!
is_first_field
)
{
// Add trailing comma and newline to previous element. Don't add trailing comma to
// Add trailing comma and newline to previous element. Don't add
// trailing comma to
// last element since older versions of gcc complain about this.
// last element since older versions of gcc complain about this.
code
+=
",
\n
"
;
code
+=
",
\n
"
;
}
else
{
}
else
{
...
@@ -332,23 +511,22 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -332,23 +511,22 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
}
}
// Generate the accessors.
// Generate the accessors.
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
// Deprecated fields won't be accessible.
if
(
!
field
.
deprecated
)
{
// Deprecated fields won't be accessible.
auto
is_scalar
=
IsScalar
(
field
.
value
.
type
.
base_type
);
auto
is_scalar
=
IsScalar
(
field
.
value
.
type
.
base_type
);
GenComment
(
field
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
GenComment
(
field
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
code
+=
" "
+
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
"const "
,
" *"
,
code
+=
" "
+
true
);
GenTypeGet
(
field
.
value
.
type
,
" "
,
"const "
,
" *"
,
true
);
code
+=
field
.
name
+
"() const { return "
;
code
+=
field
.
name
+
"() const { return "
;
// Call a different accessor for pointers, that indirects.
// Call a different accessor for pointers, that indirects.
auto
accessor
=
is_scalar
auto
accessor
=
is_scalar
?
"GetField<"
?
"GetField<"
:
(
IsStruct
(
field
.
value
.
type
)
?
"GetStruct<"
:
"GetPointer<"
);
:
(
IsStruct
(
field
.
value
.
type
)
?
"GetStruct<"
:
"GetPointer<"
);
auto
offsetstr
=
GenFieldOffsetName
(
field
);
auto
offsetstr
=
GenFieldOffsetName
(
field
);
auto
call
=
auto
call
=
accessor
+
GenTypeGet
(
field
.
value
.
type
,
""
,
accessor
+
"const "
,
" *"
,
false
)
+
GenTypeGet
(
parser
,
field
.
value
.
type
,
""
,
"const "
,
" *"
,
false
)
+
">("
+
offsetstr
;
">("
+
offsetstr
;
// Default value as second arg for non-pointer types.
// Default value as second arg for non-pointer types.
if
(
IsScalar
(
field
.
value
.
type
.
base_type
))
if
(
IsScalar
(
field
.
value
.
type
.
base_type
))
...
@@ -356,15 +534,17 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -356,15 +534,17 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
call
+=
")"
;
call
+=
")"
;
code
+=
GenUnderlyingCast
(
field
,
true
,
call
);
code
+=
GenUnderlyingCast
(
field
,
true
,
call
);
code
+=
"; }
\n
"
;
code
+=
"; }
\n
"
;
if
(
parser
.
opts
.
mutable_buffer
)
{
if
(
parser_
.
opts
.
mutable_buffer
)
{
if
(
is_scalar
)
{
if
(
is_scalar
)
{
code
+=
" bool mutate_"
+
field
.
name
+
"("
;
code
+=
" bool mutate_"
+
field
.
name
+
"("
;
code
+=
GenTypeBasic
(
field
.
value
.
type
,
true
);
code
+=
GenTypeBasic
(
field
.
value
.
type
,
true
);
code
+=
" _"
+
field
.
name
+
") { return SetField("
+
offsetstr
+
", "
;
code
+=
" _"
+
field
.
name
+
") { return SetField("
+
offsetstr
+
", "
;
code
+=
GenUnderlyingCast
(
field
,
false
,
"_"
+
field
.
name
);
code
+=
GenUnderlyingCast
(
field
,
false
,
"_"
+
field
.
name
);
code
+=
"); }
\n
"
;
code
+=
"); }
\n
"
;
}
else
{
}
else
{
auto
type
=
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
""
,
" *"
,
true
);
auto
type
=
GenTypeGet
(
field
.
value
.
type
,
" "
,
""
,
" *"
,
true
);
code
+=
" "
+
type
+
"mutable_"
+
field
.
name
+
"() { return "
;
code
+=
" "
+
type
+
"mutable_"
+
field
.
name
+
"() { return "
;
code
+=
GenUnderlyingCast
(
field
,
true
,
code
+=
GenUnderlyingCast
(
field
,
true
,
accessor
+
type
+
">("
+
offsetstr
+
")"
);
accessor
+
type
+
">("
+
offsetstr
+
")"
);
...
@@ -374,8 +554,9 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -374,8 +554,9 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
auto
nested
=
field
.
attributes
.
Lookup
(
"nested_flatbuffer"
);
auto
nested
=
field
.
attributes
.
Lookup
(
"nested_flatbuffer"
);
if
(
nested
)
{
if
(
nested
)
{
std
::
string
qualified_name
=
std
::
string
qualified_name
=
parser
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
nested
->
constant
);
parser_
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
auto
nested_root
=
parser
.
structs_
.
Lookup
(
qualified_name
);
nested
->
constant
);
auto
nested_root
=
parser_
.
structs_
.
Lookup
(
qualified_name
);
assert
(
nested_root
);
// Guaranteed to exist by parser.
assert
(
nested_root
);
// Guaranteed to exist by parser.
(
void
)
nested_root
;
(
void
)
nested_root
;
std
::
string
cpp_qualified_name
=
TranslateNameSpace
(
qualified_name
);
std
::
string
cpp_qualified_name
=
TranslateNameSpace
(
qualified_name
);
...
@@ -397,11 +578,9 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -397,11 +578,9 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
"const char *val) const { return strcmp("
+
field
.
name
;
code
+=
"const char *val) const { return strcmp("
+
field
.
name
;
code
+=
"()->c_str(), val); }
\n
"
;
code
+=
"()->c_str(), val); }
\n
"
;
}
else
{
}
else
{
if
(
parser
.
opts
.
scoped_enums
&&
if
(
parser_
.
opts
.
scoped_enums
&&
field
.
value
.
type
.
enum_def
&&
field
.
value
.
type
.
enum_def
&&
IsScalar
(
field
.
value
.
type
.
base_type
))
{
IsScalar
(
field
.
value
.
type
.
base_type
))
{
code
+=
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
"const "
,
" *"
,
code
+=
GenTypeGet
(
field
.
value
.
type
,
" "
,
"const "
,
" *"
,
true
);
true
);
}
else
{
}
else
{
code
+=
GenTypeBasic
(
field
.
value
.
type
,
false
);
code
+=
GenTypeBasic
(
field
.
value
.
type
,
false
);
}
}
...
@@ -417,18 +596,18 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -417,18 +596,18 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
" return VerifyTableStart(verifier)"
;
code
+=
" return VerifyTableStart(verifier)"
;
std
::
string
prefix
=
" &&
\n
"
;
std
::
string
prefix
=
" &&
\n
"
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
if
(
!
field
.
deprecated
)
{
code
+=
prefix
+
"VerifyField"
;
code
+=
prefix
+
"VerifyField"
;
if
(
field
.
required
)
code
+=
"Required"
;
if
(
field
.
required
)
code
+=
"Required"
;
code
+=
"<"
+
GenTypeSize
(
parser
,
field
.
value
.
type
);
code
+=
"<"
+
GenTypeSize
(
field
.
value
.
type
);
code
+=
">(verifier, "
+
GenFieldOffsetName
(
field
)
+
")"
;
code
+=
">(verifier, "
+
GenFieldOffsetName
(
field
)
+
")"
;
switch
(
field
.
value
.
type
.
base_type
)
{
switch
(
field
.
value
.
type
.
base_type
)
{
case
BASE_TYPE_UNION
:
case
BASE_TYPE_UNION
:
code
+=
prefix
+
"Verify"
+
field
.
value
.
type
.
enum_def
->
name
;
code
+=
prefix
+
"Verify"
+
field
.
value
.
type
.
enum_def
->
name
;
code
+=
"(verifier, "
+
field
.
name
+
"(), "
+
field
.
name
+
"_type())"
;
code
+=
"(verifier, "
+
field
.
name
+
"(), "
+
field
.
name
+
"_type())"
;
break
;
break
;
case
BASE_TYPE_STRUCT
:
case
BASE_TYPE_STRUCT
:
if
(
!
field
.
value
.
type
.
struct_def
->
fixed
)
{
if
(
!
field
.
value
.
type
.
struct_def
->
fixed
)
{
...
@@ -449,7 +628,8 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -449,7 +628,8 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
}
}
case
BASE_TYPE_STRUCT
:
{
case
BASE_TYPE_STRUCT
:
{
if
(
!
field
.
value
.
type
.
struct_def
->
fixed
)
{
if
(
!
field
.
value
.
type
.
struct_def
->
fixed
)
{
code
+=
prefix
+
"verifier.VerifyVectorOfTables("
+
field
.
name
;
code
+=
prefix
+
"verifier.VerifyVectorOfTables("
+
field
.
name
;
code
+=
"())"
;
code
+=
"())"
;
}
}
break
;
break
;
...
@@ -468,20 +648,20 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -468,20 +648,20 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
"};
\n\n
"
;
code
+=
"};
\n\n
"
;
// Generate a builder struct, with methods of the form:
// Generate a builder struct, with methods of the form:
// void add_name(type name) { fbb_.AddElement<type>(offset, name, default); }
// void add_name(type name) { fbb_.AddElement<type>(offset, name, default);
// }
code
+=
"struct "
+
struct_def
.
name
;
code
+=
"struct "
+
struct_def
.
name
;
code
+=
"Builder {
\n
flatbuffers::FlatBufferBuilder &fbb_;
\n
"
;
code
+=
"Builder {
\n
flatbuffers::FlatBufferBuilder &fbb_;
\n
"
;
code
+=
" flatbuffers::uoffset_t start_;
\n
"
;
code
+=
" flatbuffers::uoffset_t start_;
\n
"
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
if
(
!
field
.
deprecated
)
{
code
+=
" void add_"
+
field
.
name
+
"("
;
code
+=
" void add_"
+
field
.
name
+
"("
;
code
+=
GenTypeWire
(
parser
,
field
.
value
.
type
,
" "
,
true
)
+
field
.
name
;
code
+=
GenTypeWire
(
field
.
value
.
type
,
" "
,
true
)
+
field
.
name
;
code
+=
") { fbb_.Add"
;
code
+=
") { fbb_.Add"
;
if
(
IsScalar
(
field
.
value
.
type
.
base_type
))
{
if
(
IsScalar
(
field
.
value
.
type
.
base_type
))
{
code
+=
"Element<"
+
GenTypeWire
(
parser
,
field
.
value
.
type
,
""
,
false
);
code
+=
"Element<"
+
GenTypeWire
(
field
.
value
.
type
,
""
,
false
);
code
+=
">"
;
code
+=
">"
;
}
else
if
(
IsStruct
(
field
.
value
.
type
))
{
}
else
if
(
IsStruct
(
field
.
value
.
type
))
{
code
+=
"Struct"
;
code
+=
"Struct"
;
...
@@ -505,8 +685,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -505,8 +685,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
">(fbb_.EndTable(start_, "
;
code
+=
">(fbb_.EndTable(start_, "
;
code
+=
NumToString
(
struct_def
.
fields
.
vec
.
size
())
+
"));
\n
"
;
code
+=
NumToString
(
struct_def
.
fields
.
vec
.
size
())
+
"));
\n
"
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
&&
field
.
required
)
{
if
(
!
field
.
deprecated
&&
field
.
required
)
{
code
+=
" fbb_.Required(o, "
;
code
+=
" fbb_.Required(o, "
;
...
@@ -522,19 +701,19 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -522,19 +701,19 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
code
+=
struct_def
.
name
;
code
+=
struct_def
.
name
;
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
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
if
(
!
field
.
deprecated
)
{
code
+=
",
\n
"
+
GenTypeWire
(
parser
,
field
.
value
.
type
,
" "
,
true
);
code
+=
",
\n
"
+
GenTypeWire
(
field
.
value
.
type
,
" "
,
true
);
code
+=
field
.
name
+
" = "
;
code
+=
field
.
name
+
" = "
;
if
(
field
.
value
.
type
.
enum_def
&&
IsScalar
(
field
.
value
.
type
.
base_type
))
{
if
(
field
.
value
.
type
.
enum_def
&&
IsScalar
(
field
.
value
.
type
.
base_type
))
{
auto
ev
=
field
.
value
.
type
.
enum_def
->
ReverseLookup
(
auto
ev
=
field
.
value
.
type
.
enum_def
->
ReverseLookup
(
static_cast
<
int
>
(
StringToInt
(
field
.
value
.
constant
.
c_str
())),
false
);
static_cast
<
int
>
(
StringToInt
(
field
.
value
.
constant
.
c_str
())),
false
);
if
(
ev
)
{
if
(
ev
)
{
code
+=
WrapInNameSpace
(
field
.
value
.
type
.
enum_def
->
defined_namespace
,
code
+=
WrapInNameSpace
(
GetEnumVal
(
*
field
.
value
.
type
.
enum_def
,
*
ev
,
field
.
value
.
type
.
enum_def
->
defined_namespace
,
parser
.
opts
));
GetEnumVal
(
*
field
.
value
.
type
.
enum_def
,
*
ev
,
parser_
.
opts
));
}
else
{
}
else
{
code
+=
GenUnderlyingCast
(
field
,
true
,
field
.
value
.
constant
);
code
+=
GenUnderlyingCast
(
field
,
true
,
field
.
value
.
constant
);
}
}
...
@@ -547,25 +726,22 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
...
@@ -547,25 +726,22 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
}
}
code
+=
") {
\n
"
+
struct_def
.
name
+
"Builder builder_(_fbb);
\n
"
;
code
+=
") {
\n
"
+
struct_def
.
name
+
"Builder builder_(_fbb);
\n
"
;
for
(
size_t
size
=
struct_def
.
sortbysize
?
sizeof
(
largest_scalar_t
)
:
1
;
for
(
size_t
size
=
struct_def
.
sortbysize
?
sizeof
(
largest_scalar_t
)
:
1
;
size
;
size
;
size
/=
2
)
{
size
/=
2
)
{
for
(
auto
it
=
struct_def
.
fields
.
vec
.
rbegin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
rbegin
();
it
!=
struct_def
.
fields
.
vec
.
rend
();
it
!=
struct_def
.
fields
.
vec
.
rend
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
&&
if
(
!
field
.
deprecated
&&
(
!
struct_def
.
sortbysize
||
(
!
struct_def
.
sortbysize
||
size
==
SizeOf
(
field
.
value
.
type
.
base_type
)))
{
size
==
SizeOf
(
field
.
value
.
type
.
base_type
)))
{
code
+=
" builder_.add_"
+
field
.
name
+
"("
+
field
.
name
+
");
\n
"
;
code
+=
" builder_.add_"
+
field
.
name
+
"("
+
field
.
name
+
");
\n
"
;
}
}
}
}
}
}
code
+=
" return builder_.Finish();
\n
}
\n\n
"
;
code
+=
" return builder_.Finish();
\n
}
\n\n
"
;
}
}
static
void
GenPadding
(
const
FieldDef
&
field
,
std
::
string
&
code
,
static
void
GenPadding
(
const
FieldDef
&
field
,
std
::
string
&
code
,
int
&
padding_id
,
int
&
padding_id
,
const
std
::
function
<
void
(
int
bits
,
std
::
string
&
code
,
const
std
::
function
<
void
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
>
&
f
)
{
int
&
padding_id
)
>
&
f
)
{
if
(
field
.
padding
)
{
if
(
field
.
padding
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
...
@@ -573,26 +749,25 @@ static void GenPadding(const FieldDef &field, std::string &code,
...
@@ -573,26 +749,25 @@ static void GenPadding(const FieldDef &field, std::string &code,
f
((
1
<<
i
)
*
8
,
code
,
padding_id
);
f
((
1
<<
i
)
*
8
,
code
,
padding_id
);
assert
(
!
(
field
.
padding
&
~
0xF
));
assert
(
!
(
field
.
padding
&
~
0xF
));
}
}
}
}
static
void
PaddingDefinition
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
static
void
PaddingDefinition
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
code
+=
" int"
+
NumToString
(
bits
)
+
code
+=
" int"
+
NumToString
(
bits
)
+
"_t __padding"
+
"_t __padding"
+
NumToString
(
padding_id
++
)
+
";
\n
"
;
NumToString
(
padding_id
++
)
+
";
\n
"
;
}
}
static
void
PaddingDeclaration
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
static
void
PaddingDeclaration
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
(
void
)
bits
;
(
void
)
bits
;
code
+=
" (void)__padding"
+
NumToString
(
padding_id
++
)
+
";"
;
code
+=
" (void)__padding"
+
NumToString
(
padding_id
++
)
+
";"
;
}
}
static
void
PaddingInitializer
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
static
void
PaddingInitializer
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
(
void
)
bits
;
(
void
)
bits
;
code
+=
", __padding"
+
NumToString
(
padding_id
++
)
+
"(0)"
;
code
+=
", __padding"
+
NumToString
(
padding_id
++
)
+
"(0)"
;
}
}
// Generate an accessor struct with constructor for a flatbuffers struct.
// Generate an accessor struct with constructor for a flatbuffers struct.
static
void
GenStruct
(
const
Parser
&
parser
,
StructDef
&
struct_def
,
void
GenStruct
(
StructDef
&
struct_def
,
std
::
string
*
code_ptr
)
{
std
::
string
*
code_ptr
)
{
if
(
struct_def
.
generated
)
return
;
if
(
struct_def
.
generated
)
return
;
std
::
string
&
code
=
*
code_ptr
;
std
::
string
&
code
=
*
code_ptr
;
...
@@ -602,37 +777,35 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
...
@@ -602,37 +777,35 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
// Variables are private because they contain little endian data on all
// Variables are private because they contain little endian data on all
// platforms.
// platforms.
GenComment
(
struct_def
.
doc_comment
,
code_ptr
,
nullptr
);
GenComment
(
struct_def
.
doc_comment
,
code_ptr
,
nullptr
);
code
+=
"MANUALLY_ALIGNED_STRUCT("
+
NumToString
(
struct_def
.
minalign
)
+
") "
;
code
+=
"MANUALLY_ALIGNED_STRUCT("
+
NumToString
(
struct_def
.
minalign
)
+
") "
;
code
+=
struct_def
.
name
+
" FLATBUFFERS_FINAL_CLASS {
\n
private:
\n
"
;
code
+=
struct_def
.
name
+
" FLATBUFFERS_FINAL_CLASS {
\n
private:
\n
"
;
int
padding_id
=
0
;
int
padding_id
=
0
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
code
+=
" "
+
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
""
,
" "
,
false
);
code
+=
" "
+
GenTypeGet
(
field
.
value
.
type
,
" "
,
""
,
" "
,
false
);
code
+=
field
.
name
+
"_;
\n
"
;
code
+=
field
.
name
+
"_;
\n
"
;
GenPadding
(
field
,
code
,
padding_id
,
PaddingDefinition
);
GenPadding
(
field
,
code
,
padding_id
,
PaddingDefinition
);
}
}
// Generate GetFullyQualifiedName
// Generate GetFullyQualifiedName
code
+=
"
\n
public:
\n
"
;
code
+=
"
\n
public:
\n
"
;
GenFullyQualifiedNameGetter
(
parser
,
struct_def
.
name
,
code
);
GenFullyQualifiedNameGetter
(
struct_def
.
name
,
code
);
// Generate a constructor that takes all fields as arguments.
// Generate a constructor that takes all fields as arguments.
code
+=
" "
+
struct_def
.
name
+
"("
;
code
+=
" "
+
struct_def
.
name
+
"("
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
it
!=
struct_def
.
fields
.
vec
.
begin
())
code
+=
", "
;
if
(
it
!=
struct_def
.
fields
.
vec
.
begin
())
code
+=
", "
;
code
+=
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
"const "
,
" &"
,
true
);
code
+=
GenTypeGet
(
field
.
value
.
type
,
" "
,
"const "
,
" &"
,
true
);
code
+=
"_"
+
field
.
name
;
code
+=
"_"
+
field
.
name
;
}
}
code
+=
")
\n
: "
;
code
+=
")
\n
: "
;
padding_id
=
0
;
padding_id
=
0
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
if
(
it
!=
struct_def
.
fields
.
vec
.
begin
())
code
+=
", "
;
if
(
it
!=
struct_def
.
fields
.
vec
.
begin
())
code
+=
", "
;
code
+=
field
.
name
+
"_("
;
code
+=
field
.
name
+
"_("
;
...
@@ -649,8 +822,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
...
@@ -649,8 +822,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
code
+=
" {"
;
code
+=
" {"
;
padding_id
=
0
;
padding_id
=
0
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
GenPadding
(
field
,
code
,
padding_id
,
PaddingDeclaration
);
GenPadding
(
field
,
code
,
padding_id
,
PaddingDeclaration
);
}
}
...
@@ -659,20 +831,19 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
...
@@ -659,20 +831,19 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
// Generate accessor methods of the form:
// Generate accessor methods of the form:
// type name() const { return flatbuffers::EndianScalar(name_); }
// type name() const { return flatbuffers::EndianScalar(name_); }
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
++
it
)
{
auto
&
field
=
**
it
;
auto
&
field
=
**
it
;
GenComment
(
field
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
GenComment
(
field
.
doc_comment
,
code_ptr
,
nullptr
,
" "
);
auto
is_scalar
=
IsScalar
(
field
.
value
.
type
.
base_type
);
auto
is_scalar
=
IsScalar
(
field
.
value
.
type
.
base_type
);
code
+=
" "
+
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
"const "
,
" &"
,
code
+=
" "
+
true
);
GenTypeGet
(
field
.
value
.
type
,
" "
,
"const "
,
" &"
,
true
);
code
+=
field
.
name
+
"() const { return "
;
code
+=
field
.
name
+
"() const { return "
;
code
+=
GenUnderlyingCast
(
field
,
true
,
code
+=
GenUnderlyingCast
(
is_scalar
field
,
true
,
is_scalar
?
"flatbuffers::EndianScalar("
+
field
.
name
+
"_)"
?
"flatbuffers::EndianScalar("
+
field
.
name
+
"_)"
:
field
.
name
+
"_"
);
:
field
.
name
+
"_"
);
code
+=
"; }
\n
"
;
code
+=
"; }
\n
"
;
if
(
parser
.
opts
.
mutable_buffer
)
{
if
(
parser_
.
opts
.
mutable_buffer
)
{
if
(
is_scalar
)
{
if
(
is_scalar
)
{
code
+=
" void mutate_"
+
field
.
name
+
"("
;
code
+=
" void mutate_"
+
field
.
name
+
"("
;
code
+=
GenTypeBasic
(
field
.
value
.
type
,
true
);
code
+=
GenTypeBasic
(
field
.
value
.
type
,
true
);
...
@@ -682,7 +853,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
...
@@ -682,7 +853,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
code
+=
"); }
\n
"
;
code
+=
"); }
\n
"
;
}
else
{
}
else
{
code
+=
" "
;
code
+=
" "
;
code
+=
GenTypeGet
(
parser
,
field
.
value
.
type
,
""
,
""
,
" &"
,
true
);
code
+=
GenTypeGet
(
field
.
value
.
type
,
""
,
""
,
" &"
,
true
);
code
+=
"mutable_"
+
field
.
name
+
"() { return "
+
field
.
name
;
code
+=
"mutable_"
+
field
.
name
+
"() { return "
+
field
.
name
;
code
+=
"_; }
\n
"
;
code
+=
"_; }
\n
"
;
}
}
...
@@ -690,21 +861,21 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
...
@@ -690,21 +861,21 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
}
}
code
+=
"};
\n
STRUCT_END("
+
struct_def
.
name
+
", "
;
code
+=
"};
\n
STRUCT_END("
+
struct_def
.
name
+
", "
;
code
+=
NumToString
(
struct_def
.
bytesize
)
+
");
\n\n
"
;
code
+=
NumToString
(
struct_def
.
bytesize
)
+
");
\n\n
"
;
}
}
void
GenerateNestedNameSpaces
(
const
Namespace
*
ns
,
std
::
string
*
code_ptr
)
{
void
GenerateNestedNameSpaces
(
const
Namespace
*
ns
,
std
::
string
*
code_ptr
)
{
for
(
auto
it
=
ns
->
components
.
begin
();
it
!=
ns
->
components
.
end
();
++
it
)
{
for
(
auto
it
=
ns
->
components
.
begin
();
it
!=
ns
->
components
.
end
();
++
it
)
{
*
code_ptr
+=
"namespace "
+
*
it
+
" {
\n
"
;
*
code_ptr
+=
"namespace "
+
*
it
+
" {
\n
"
;
}
}
}
}
void
CloseNestedNameSpaces
(
const
Namespace
*
ns
,
std
::
string
*
code_ptr
)
{
void
CloseNestedNameSpaces
(
const
Namespace
*
ns
,
std
::
string
*
code_ptr
)
{
for
(
auto
it
=
ns
->
components
.
rbegin
();
it
!=
ns
->
components
.
rend
();
++
it
)
{
for
(
auto
it
=
ns
->
components
.
rbegin
();
it
!=
ns
->
components
.
rend
();
++
it
)
{
*
code_ptr
+=
"} // namespace "
+
*
it
+
"
\n
"
;
*
code_ptr
+=
"} // namespace "
+
*
it
+
"
\n
"
;
}
}
}
}
void
CheckNameSpace
(
const
Definition
&
def
,
std
::
string
*
code_ptr
)
{
void
CheckNameSpace
(
const
Definition
&
def
,
std
::
string
*
code_ptr
)
{
// Set up the correct namespace. Only open a namespace if
// Set up the correct namespace. Only open a namespace if
// the existing one is different.
// the existing one is different.
// TODO: this could be done more intelligently, by sorting to
// TODO: this could be done more intelligently, by sorting to
...
@@ -719,191 +890,6 @@ void CheckNameSpace(const Definition &def, std::string *code_ptr) {
...
@@ -719,191 +890,6 @@ void CheckNameSpace(const Definition &def, std::string *code_ptr) {
code_generator_cur_name_space
=
def
.
defined_namespace
;
code_generator_cur_name_space
=
def
.
defined_namespace
;
if
(
code_generator_cur_name_space
->
components
.
size
())
*
code_ptr
+=
"
\n
"
;
if
(
code_generator_cur_name_space
->
components
.
size
())
*
code_ptr
+=
"
\n
"
;
}
}
}
}
// namespace cpp
struct
IsAlnum
{
bool
operator
()(
char
c
)
{
return
!
isalnum
(
c
);
}
};
static
std
::
string
GeneratedFileName
(
const
std
::
string
&
path
,
const
std
::
string
&
file_name
)
{
return
path
+
file_name
+
"_generated.h"
;
}
namespace
cpp
{
class
CppGenerator
:
public
BaseGenerator
{
public
:
CppGenerator
(
const
Parser
&
parser
,
const
std
::
string
&
path
,
const
std
::
string
&
file_name
)
:
BaseGenerator
(
parser
,
path
,
file_name
){};
// Iterate through all definitions we haven't generate code for (enums,
// structs,
// and tables) and output them to a single file.
bool
generate
()
{
if
(
IsEverythingGenerated
())
return
true
;
std
::
string
code
;
code
=
code
+
"// "
+
FlatBuffersGeneratedWarning
();
// Generate include guard.
std
::
string
include_guard_ident
=
file_name_
;
// Remove any non-alpha-numeric characters that may appear in a filename.
include_guard_ident
.
erase
(
std
::
remove_if
(
include_guard_ident
.
begin
(),
include_guard_ident
.
end
(),
IsAlnum
()),
include_guard_ident
.
end
());
std
::
string
include_guard
=
"FLATBUFFERS_GENERATED_"
+
include_guard_ident
;
include_guard
+=
"_"
;
// For further uniqueness, also add the namespace.
auto
name_space
=
parser_
.
namespaces_
.
back
();
for
(
auto
it
=
name_space
->
components
.
begin
();
it
!=
name_space
->
components
.
end
();
++
it
)
{
include_guard
+=
*
it
+
"_"
;
}
include_guard
+=
"H_"
;
std
::
transform
(
include_guard
.
begin
(),
include_guard
.
end
(),
include_guard
.
begin
(),
::
toupper
);
code
+=
"#ifndef "
+
include_guard
+
"
\n
"
;
code
+=
"#define "
+
include_guard
+
"
\n\n
"
;
code
+=
"#include
\"
flatbuffers/flatbuffers.h
\"\n\n
"
;
if
(
parser_
.
opts
.
include_dependence_headers
)
{
int
num_includes
=
0
;
for
(
auto
it
=
parser_
.
included_files_
.
begin
();
it
!=
parser_
.
included_files_
.
end
();
++
it
)
{
auto
basename
=
flatbuffers
::
StripPath
(
flatbuffers
::
StripExtension
(
it
->
first
));
if
(
basename
!=
file_name_
)
{
code
+=
"#include
\"
"
+
basename
+
"_generated.h
\"\n
"
;
num_includes
++
;
}
}
if
(
num_includes
)
code
+=
"
\n
"
;
}
assert
(
!
code_generator_cur_name_space
);
// Generate forward declarations for all structs/tables, since they may
// have circular references.
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
code
+=
"struct "
+
struct_def
.
name
+
";
\n\n
"
;
}
}
// Generate code for all the enum declarations.
for
(
auto
it
=
parser_
.
enums_
.
vec
.
begin
();
it
!=
parser_
.
enums_
.
vec
.
end
();
++
it
)
{
auto
&
enum_def
=
**
it
;
if
(
!
enum_def
.
generated
)
{
CheckNameSpace
(
**
it
,
&
code
);
GenEnum
(
parser_
,
**
it
,
&
code
);
}
}
// Generate code for all structs, then all tables.
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
struct_def
.
fixed
&&
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
GenStruct
(
parser_
,
struct_def
,
&
code
);
}
}
for
(
auto
it
=
parser_
.
structs_
.
vec
.
begin
();
it
!=
parser_
.
structs_
.
vec
.
end
();
++
it
)
{
auto
&
struct_def
=
**
it
;
if
(
!
struct_def
.
fixed
&&
!
struct_def
.
generated
)
{
CheckNameSpace
(
struct_def
,
&
code
);
GenTable
(
parser_
,
struct_def
,
&
code
);
}
}
// Generate code for union verifiers.
for
(
auto
it
=
parser_
.
enums_
.
vec
.
begin
();
it
!=
parser_
.
enums_
.
vec
.
end
();
++
it
)
{
auto
&
enum_def
=
**
it
;
if
(
enum_def
.
is_union
&&
!
enum_def
.
generated
)
{
CheckNameSpace
(
enum_def
,
&
code
);
GenEnumPost
(
parser_
,
enum_def
,
&
code
);
}
}
// Generate convenient global helper functions:
if
(
parser_
.
root_struct_def_
)
{
CheckNameSpace
(
*
parser_
.
root_struct_def_
,
&
code
);
auto
&
name
=
parser_
.
root_struct_def_
->
name
;
std
::
string
qualified_name
=
parser_
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
name
);
std
::
string
cpp_qualified_name
=
TranslateNameSpace
(
qualified_name
);
// The root datatype accessor:
code
+=
"inline const "
+
cpp_qualified_name
+
" *Get"
;
code
+=
name
;
code
+=
"(const void *buf) { return flatbuffers::GetRoot<"
;
code
+=
cpp_qualified_name
+
">(buf); }
\n\n
"
;
if
(
parser_
.
opts
.
mutable_buffer
)
{
code
+=
"inline "
+
name
+
" *GetMutable"
;
code
+=
name
;
code
+=
"(void *buf) { return flatbuffers::GetMutableRoot<"
;
code
+=
name
+
">(buf); }
\n\n
"
;
}
// The root verifier:
code
+=
"inline bool Verify"
;
code
+=
name
;
code
+=
"Buffer(flatbuffers::Verifier &verifier) { "
"return verifier.VerifyBuffer<"
;
code
+=
cpp_qualified_name
+
">(); }
\n\n
"
;
if
(
parser_
.
file_identifier_
.
length
())
{
// Return the identifier
code
+=
"inline const char *"
+
name
;
code
+=
"Identifier() { return
\"
"
+
parser_
.
file_identifier_
;
code
+=
"
\"
; }
\n\n
"
;
// Check if a buffer has the identifier.
code
+=
"inline bool "
+
name
;
code
+=
"BufferHasIdentifier(const void *buf) { return flatbuffers::"
;
code
+=
"BufferHasIdentifier(buf, "
;
code
+=
name
+
"Identifier()); }
\n\n
"
;
}
if
(
parser_
.
file_extension_
.
length
())
{
// Return the extension
code
+=
"inline const char *"
+
name
;
code
+=
"Extension() { return
\"
"
+
parser_
.
file_extension_
;
code
+=
"
\"
; }
\n\n
"
;
}
// Finish a buffer with a given root object:
code
+=
"inline void Finish"
+
name
;
code
+=
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<"
;
code
+=
cpp_qualified_name
+
"> root) { fbb.Finish(root"
;
if
(
parser_
.
file_identifier_
.
length
())
code
+=
", "
+
name
+
"Identifier()"
;
code
+=
"); }
\n\n
"
;
}
assert
(
code_generator_cur_name_space
);
CloseNestedNameSpaces
(
code_generator_cur_name_space
,
&
code
);
code_generator_cur_name_space
=
nullptr
;
// Close the include guard.
code
+=
"
\n
#endif // "
+
include_guard
+
"
\n
"
;
return
SaveFile
(
GeneratedFileName
(
path_
,
file_name_
).
c_str
(),
code
,
false
);
}
}
};
};
}
// namespace cpp
}
// namespace cpp
...
...
tests/monster_test_generated.h
View file @
a9194c4c
...
@@ -22,8 +22,8 @@ enum Color {
...
@@ -22,8 +22,8 @@ enum Color {
Color_Red
=
1
,
Color_Red
=
1
,
Color_Green
=
2
,
Color_Green
=
2
,
Color_Blue
=
8
,
Color_Blue
=
8
,
Color_
MIN
=
Color_Red
,
Color_
NONE
=
0
,
Color_
MAX
=
Color_Blue
Color_
ANY
=
11
};
};
inline
const
char
**
EnumNamesColor
()
{
inline
const
char
**
EnumNamesColor
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment