Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
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
capnproto
Commits
0c7c610c
Commit
0c7c610c
authored
Aug 21, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More WIP.
parent
1dcb66b1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
358 additions
and
590 deletions
+358
-590
capnpc-c++.c++
c++/src/capnp/compiler/capnpc-c++.c++
+252
-508
node-translator.c++
c++/src/capnp/compiler/node-translator.c++
+30
-14
generated-header-support.h
c++/src/capnp/generated-header-support.h
+2
-1
schema-loader.c++
c++/src/capnp/schema-loader.c++
+39
-13
schema.h
c++/src/capnp/schema.h
+0
-2
schema2.capnp
c++/src/capnp/schema2.capnp
+3
-2
stringify.c++
c++/src/capnp/stringify.c++
+32
-50
No files found.
c++/src/capnp/compiler/capnpc-c++.c++
View file @
0c7c610c
...
...
@@ -59,52 +59,46 @@ static constexpr const char* FIELD_SIZE_NAMES[] = {
"VOID"
,
"BIT"
,
"BYTE"
,
"TWO_BYTES"
,
"FOUR_BYTES"
,
"EIGHT_BYTES"
,
"POINTER"
,
"INLINE_COMPOSITE"
};
void
enumerateDeps
(
schema
::
Type
::
Reader
type
,
std
::
set
<
uint64_t
>&
deps
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
deps
.
insert
(
type
.
get
Body
().
getStructType
());
void
enumerateDeps
(
schema
2
::
Type
::
Reader
type
,
std
::
set
<
uint64_t
>&
deps
)
{
switch
(
type
.
which
())
{
case
schema
2
:
:
Type
::
STRUCT
:
deps
.
insert
(
type
.
get
Struct
());
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
deps
.
insert
(
type
.
get
Body
().
getEnumType
());
case
schema
2
:
:
Type
::
ENUM
:
deps
.
insert
(
type
.
get
Enum
());
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYP
E
:
deps
.
insert
(
type
.
get
Body
().
getInterfaceTyp
e
());
case
schema
2
:
:
Type
::
INTERFAC
E
:
deps
.
insert
(
type
.
get
Interfac
e
());
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
enumerateDeps
(
type
.
get
Body
().
getListType
(),
deps
);
case
schema
2
:
:
Type
::
LIST
:
enumerateDeps
(
type
.
get
List
(),
deps
);
break
;
default:
break
;
}
}
void
enumerateDeps
(
schema
::
StructNode
::
Member
::
Reader
member
,
std
::
set
<
uint64_t
>&
deps
)
{
switch
(
member
.
getBody
()
.
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
enumerateDeps
(
member
.
getBody
().
getFieldMember
().
getType
(),
deps
);
break
;
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
for
(
auto
subMember
:
member
.
getBody
().
getUnionMember
().
getMembers
())
{
enumerateDeps
(
subMember
,
deps
);
}
break
;
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
for
(
auto
subMember
:
member
.
getBody
().
getGroupMember
().
getMembers
())
{
enumerateDeps
(
subMember
,
deps
);
void
enumerateDeps
(
schema
2
::
Node
::
Reader
node
,
std
::
set
<
uint64_t
>&
deps
)
{
switch
(
node
.
which
())
{
case
schema
2
:
:
Node
::
STRUCT
:
{
auto
structNode
=
node
.
getStruct
(
);
for
(
auto
field
:
structNode
.
getFields
())
{
switch
(
field
.
which
())
{
case
schema2
:
:
Field
::
REGULAR
:
enumerateDeps
(
field
.
getRegular
().
getType
()
,
deps
);
break
;
case
schema2
:
:
Field
::
GROUP
:
deps
.
insert
(
field
.
getGroup
());
break
;
}
}
break
;
}
}
void
enumerateDeps
(
schema
::
Node
::
Reader
node
,
std
::
set
<
uint64_t
>&
deps
)
{
switch
(
node
.
getBody
().
which
())
{
case
schema
:
:
Node
::
Body
::
STRUCT_NODE
:
for
(
auto
member
:
node
.
getBody
().
getStructNode
().
getMembers
())
{
enumerateDeps
(
member
,
deps
);
if
(
structNode
.
getIsGroup
())
{
deps
.
insert
(
node
.
getScopeId
());
}
break
;
case
schema
:
:
Node
::
Body
::
INTERFACE_NODE
:
for
(
auto
method
:
node
.
getBody
().
getInterfaceNode
().
getMethods
())
{
}
case
schema2
:
:
Node
::
INTERFACE
:
for
(
auto
method
:
node
.
getInterface
())
{
for
(
auto
param
:
method
.
getParams
())
{
enumerateDeps
(
param
.
getType
(),
deps
);
}
...
...
@@ -119,92 +113,15 @@ void enumerateDeps(schema::Node::Reader node, std::set<uint64_t>& deps) {
struct
OrderByName
{
template
<
typename
T
>
inline
bool
operator
()(
const
T
&
a
,
const
T
&
b
)
const
{
return
a
.
member
.
getProto
().
getName
()
<
b
.
member
.
getProto
().
getName
();
}
};
template
<
typename
MemberList
>
void
makeMemberInfoTable
(
uint
parent
,
MemberList
&&
members
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
);
void
makeSubMemberInfoTable
(
const
StructSchema
::
Member
&
member
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
break
;
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
// Only create a sub-table if the union is named.
if
(
member
.
getProto
().
getName
().
size
()
>
0
)
{
makeMemberInfoTable
(
1
+
member
.
getProto
().
getOrdinal
(),
member
.
asUnion
().
getMembers
(),
info
);
}
break
;
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
makeMemberInfoTable
(
1
+
member
.
getProto
().
getOrdinal
(),
member
.
asGroup
().
getMembers
(),
info
);
break
;
return
a
.
getProto
().
getName
()
<
b
.
getProto
().
getName
();
}
}
void
makeSubMemberInfoTable
(
const
EnumSchema
::
Enumerant
&
member
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{}
void
makeSubMemberInfoTable
(
const
InterfaceSchema
::
Method
&
member
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{}
template
<
typename
Member
>
struct
MemberAndIndex
{
Member
member
;
uint
index
;
MemberAndIndex
(
Member
member
)
:
member
(
member
),
index
(
member
.
getIndex
())
{}
MemberAndIndex
(
Member
member
,
uint
index
)
:
member
(
member
),
index
(
index
)
{}
};
void
enumerateScope
(
const
StructSchema
::
MemberList
&
members
,
kj
::
Vector
<
MemberAndIndex
<
StructSchema
::
Member
>>&
vec
,
uint
offset
=
0
)
{
// Given a member list, flatten all members of the scope into one vector. This basically means
// copying all the members to the vector, except that unnamed unions are flattened, with their
// members' indexes being offset by the size of the parent scope.
for
(
auto
member
:
members
)
{
vec
.
add
(
member
,
member
.
getIndex
()
+
offset
);
if
(
member
.
getProto
().
getName
().
size
()
==
0
)
{
// Flatten unnamed union.
enumerateScope
(
member
.
asUnion
().
getMembers
(),
vec
,
offset
+
members
.
size
());
}
}
}
void
enumerateScope
(
const
EnumSchema
::
EnumerantList
&
members
,
kj
::
Vector
<
MemberAndIndex
<
EnumSchema
::
Enumerant
>>&
vec
)
{
for
(
auto
member
:
members
)
{
vec
.
add
(
member
);
}
}
void
enumerateScope
(
const
InterfaceSchema
::
MethodList
&
members
,
kj
::
Vector
<
MemberAndIndex
<
InterfaceSchema
::
Method
>>&
vec
)
{
for
(
auto
member
:
members
)
{
vec
.
add
(
member
);
}
}
template
<
typename
MemberList
>
void
makeMemberInfoTable
(
uint
parent
,
MemberList
&&
members
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{
kj
::
Vector
<
MemberAndIndex
<
decltype
(
members
[
0
])
>>
sorted
(
members
.
size
());
enumerateScope
(
members
,
sorted
);
kj
::
Array
<
uint
>
makeMembersByName
(
MemberList
&&
members
)
{
auto
sorted
=
KJ_MAP
(
members
,
member
)
{
return
member
;
};
std
::
sort
(
sorted
.
begin
(),
sorted
.
end
(),
OrderByName
());
for
(
auto
&
member
:
sorted
)
{
info
.
add
(
capnp
::
_
::
RawSchema
::
MemberInfo
{
kj
::
implicitCast
<
uint16_t
>
(
parent
),
kj
::
implicitCast
<
uint16_t
>
(
member
.
index
)
});
}
for
(
auto
member
:
members
)
{
makeSubMemberInfoTable
(
member
,
info
);
}
return
KJ_MAP
(
sorted
,
member
)
{
return
member
.
getIndex
();
};
}
kj
::
StringPtr
baseName
(
kj
::
StringPtr
path
)
{
...
...
@@ -242,7 +159,7 @@ private:
usedImports
.
insert
(
node
.
getId
());
for
(
auto
annotation
:
node
.
getAnnotations
())
{
if
(
annotation
.
getId
()
==
NAMESPACE_ANNOTATION_ID
)
{
return
kj
::
strTree
(
" ::"
,
annotation
.
getValue
().
get
Body
().
getTextValue
());
return
kj
::
strTree
(
" ::"
,
annotation
.
getValue
().
get
Text
());
}
}
return
kj
::
strTree
(
" "
);
...
...
@@ -284,36 +201,36 @@ private:
return
kj
::
mv
(
result
);
}
kj
::
StringTree
typeName
(
schema
::
Type
::
Reader
type
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
return
kj
::
strTree
(
" ::capnp::Void"
);
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
return
kj
::
strTree
(
"bool"
);
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
return
kj
::
strTree
(
" ::int8_t"
);
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
return
kj
::
strTree
(
" ::int16_t"
);
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
return
kj
::
strTree
(
" ::int32_t"
);
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
return
kj
::
strTree
(
" ::int64_t"
);
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
return
kj
::
strTree
(
" ::uint8_t"
);
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
return
kj
::
strTree
(
" ::uint16_t"
);
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
return
kj
::
strTree
(
" ::uint32_t"
);
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
return
kj
::
strTree
(
" ::uint64_t"
);
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
return
kj
::
strTree
(
"float"
);
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
return
kj
::
strTree
(
"double"
);
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
return
kj
::
strTree
(
" ::capnp::Text"
);
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
return
kj
::
strTree
(
" ::capnp::Data"
);
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Body
().
getEnumType
()));
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Body
().
getStructType
()));
case
schema
:
:
Type
::
Body
::
INTERFACE_TYP
E
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Body
().
getInterfaceTyp
e
()));
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
return
kj
::
strTree
(
" ::capnp::List<"
,
typeName
(
type
.
get
Body
().
getListType
()),
">"
);
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
kj
::
StringTree
typeName
(
schema
2
::
Type
::
Reader
type
)
{
switch
(
type
.
which
())
{
case
schema
2
:
:
Type
::
VOID
:
return
kj
::
strTree
(
" ::capnp::Void"
);
case
schema
2
:
:
Type
::
BOOL
:
return
kj
::
strTree
(
"bool"
);
case
schema
2
:
:
Type
::
INT8
:
return
kj
::
strTree
(
" ::int8_t"
);
case
schema
2
:
:
Type
::
INT16
:
return
kj
::
strTree
(
" ::int16_t"
);
case
schema
2
:
:
Type
::
INT32
:
return
kj
::
strTree
(
" ::int32_t"
);
case
schema
2
:
:
Type
::
INT64
:
return
kj
::
strTree
(
" ::int64_t"
);
case
schema
2
:
:
Type
::
UINT8
:
return
kj
::
strTree
(
" ::uint8_t"
);
case
schema
2
:
:
Type
::
UINT16
:
return
kj
::
strTree
(
" ::uint16_t"
);
case
schema
2
:
:
Type
::
UINT32
:
return
kj
::
strTree
(
" ::uint32_t"
);
case
schema
2
:
:
Type
::
UINT64
:
return
kj
::
strTree
(
" ::uint64_t"
);
case
schema
2
:
:
Type
::
FLOAT32
:
return
kj
::
strTree
(
"float"
);
case
schema
2
:
:
Type
::
FLOAT64
:
return
kj
::
strTree
(
"double"
);
case
schema
2
:
:
Type
::
TEXT
:
return
kj
::
strTree
(
" ::capnp::Text"
);
case
schema
2
:
:
Type
::
DATA
:
return
kj
::
strTree
(
" ::capnp::Data"
);
case
schema
2
:
:
Type
::
ENUM
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Enum
()));
case
schema
2
:
:
Type
::
STRUCT
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Struct
()));
case
schema
2
:
:
Type
::
INTERFAC
E
:
return
cppFullName
(
schemaLoader
.
get
(
type
.
get
Interfac
e
()));
case
schema
2
:
:
Type
::
LIST
:
return
kj
::
strTree
(
" ::capnp::List<"
,
typeName
(
type
.
get
List
()),
">"
);
case
schema
2
:
:
Type
::
OBJECT
:
// Not used.
return
kj
::
strTree
();
}
...
...
@@ -329,29 +246,19 @@ private:
DiscriminantChecks
makeDiscriminantChecks
(
kj
::
StringPtr
scope
,
kj
::
StringPtr
memberName
,
StructSchema
::
Union
containingUnion
)
{
auto
unionProto
=
containingUnion
.
getProto
();
kj
::
StringPtr
unionScope
;
kj
::
String
ownUnionScope
;
if
(
unionProto
.
getName
().
size
()
>
0
)
{
ownUnionScope
=
kj
::
str
(
toTitleCase
(
unionProto
.
getName
()),
"::"
);
unionScope
=
ownUnionScope
;
}
else
{
// Anonymous union.
unionScope
=
scope
;
}
auto
discrimOffset
=
unionProto
.
getBody
().
getUnionMember
().
getDiscriminantOffset
();
StructSchema
containingStruct
)
{
auto
discrimOffset
=
containingStruct
.
getProto
().
getStruct
().
getDiscriminantOffset
();
kj
::
String
upperCase
=
toUpperCase
(
memberName
);
return
DiscriminantChecks
{
kj
::
str
(
" KJ_IREQUIRE(which() == "
,
unionS
cope
,
upperCase
,
",
\n
"
" KJ_IREQUIRE(which() == "
,
s
cope
,
upperCase
,
",
\n
"
"
\"
Must check which() before get()ing a union member.
\"
);
\n
"
),
kj
::
str
(
" _builder.setDataField<"
,
unionS
cope
,
"Which>(
\n
"
" _builder.setDataField<"
,
s
cope
,
"Which>(
\n
"
" "
,
discrimOffset
,
" * ::capnp::ELEMENTS, "
,
unionS
cope
,
upperCase
,
");
\n
"
)
s
cope
,
upperCase
,
");
\n
"
)
};
}
...
...
@@ -372,31 +279,71 @@ private:
OBJECT
};
FieldText
makeFieldText
(
kj
::
StringPtr
scope
,
StructSchema
::
Field
member
)
{
auto
proto
=
member
.
getProto
();
auto
field
=
proto
.
getBody
().
getFieldMember
();
FieldText
makeFieldText
(
kj
::
StringPtr
scope
,
StructSchema
::
Field
field
)
{
auto
proto
=
field
.
getProto
();
kj
::
String
titleCase
=
toTitleCase
(
proto
.
getName
());
DiscriminantChecks
unionDiscrim
;
if
(
proto
.
hasDiscriminantValue
())
{
unionDiscrim
=
makeDiscriminantChecks
(
scope
,
proto
.
getName
(),
field
.
getContainingStruct
());
}
switch
(
proto
.
which
())
{
case
schema2
:
:
Field
::
REGULAR
:
// Continue below.
break
;
case
schema2
:
:
Field
::
GROUP
:
return
FieldText
{
kj
::
strTree
(
" inline "
,
titleCase
,
"::Reader get"
,
titleCase
,
"() const;
\n
"
"
\n
"
),
kj
::
strTree
(
" inline "
,
titleCase
,
"::Builder get"
,
titleCase
,
"();
\n
"
" inline "
,
titleCase
,
"::Builder init"
,
titleCase
,
"();
\n
"
"
\n
"
),
kj
::
strTree
(
"inline "
,
scope
,
titleCase
,
"::Reader "
,
scope
,
"Reader::get"
,
titleCase
,
"() const {
\n
"
,
unionDiscrim
.
check
,
" return "
,
scope
,
titleCase
,
"::Reader(_reader);
\n
"
"}
\n
"
"inline "
,
scope
,
titleCase
,
"::Builder "
,
scope
,
"Builder::get"
,
titleCase
,
"() {
\n
"
,
unionDiscrim
.
check
,
" return "
,
scope
,
titleCase
,
"::Builder(_builder);
\n
"
"}
\n
"
"inline "
,
scope
,
titleCase
,
"::Builder "
,
scope
,
"Builder::init"
,
titleCase
,
"() {
\n
"
,
unionDiscrim
.
set
,
// TODO(soon): Zero out fields.
" return "
,
scope
,
titleCase
,
"::Builder(_builder);
\n
"
"}
\n
"
)
};
}
auto
regularField
=
proto
.
getRegular
();
FieldKind
kind
;
kj
::
String
ownedType
;
kj
::
String
type
=
typeName
(
f
ield
.
getType
()).
flatten
();
kj
::
String
type
=
typeName
(
regularF
ield
.
getType
()).
flatten
();
kj
::
StringPtr
setterDefault
;
// only for void
kj
::
String
defaultMask
;
// primitives only
size_t
defaultOffset
=
0
;
// pointers only: offset of the default value within the schema.
size_t
defaultSize
=
0
;
// blobs only: byte size of the default value.
auto
typeBody
=
field
.
getType
().
getBody
();
auto
defaultBody
=
field
.
getDefaultValue
().
getBody
();
auto
typeBody
=
regularField
.
getType
();
auto
defaultBody
=
regularField
.
getDefaultValue
();
switch
(
typeBody
.
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
case
schema
2
:
:
Type
::
VOID
:
kind
=
FieldKind
::
PRIMITIVE
;
setterDefault
=
" = ::capnp::Void::VOID"
;
break
;
#define HANDLE_PRIMITIVE(discrim, typeName, defaultName, suffix) \
case schema
::Type::Body::discrim##_TYPE
: \
case schema
2::Type::discrim
: \
kind = FieldKind::PRIMITIVE; \
if (defaultBody.get##defaultName
##Value
() != 0) { \
defaultMask = kj::str(defaultBody.get##defaultName
##Value
(), #suffix); \
if (defaultBody.get##defaultName() != 0) { \
defaultMask = kj::str(defaultBody.get##defaultName(), #suffix); \
} \
break;
...
...
@@ -411,69 +358,69 @@ private:
HANDLE_PRIMITIVE
(
UINT64
,
::
uint64_t
,
Uint64
,
ull
);
#undef HANDLE_PRIMITIVE
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
case
schema
2
:
:
Type
::
FLOAT32
:
kind
=
FieldKind
::
PRIMITIVE
;
if
(
defaultBody
.
getFloat32
Value
()
!=
0
)
{
if
(
defaultBody
.
getFloat32
()
!=
0
)
{
uint32_t
mask
;
float
value
=
defaultBody
.
getFloat32
Value
();
float
value
=
defaultBody
.
getFloat32
();
static_assert
(
sizeof
(
mask
)
==
sizeof
(
value
),
"bug"
);
memcpy
(
&
mask
,
&
value
,
sizeof
(
mask
));
defaultMask
=
kj
::
str
(
mask
,
"u"
);
}
break
;
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
case
schema
2
:
:
Type
::
FLOAT64
:
kind
=
FieldKind
::
PRIMITIVE
;
if
(
defaultBody
.
getFloat64
Value
()
!=
0
)
{
if
(
defaultBody
.
getFloat64
()
!=
0
)
{
uint64_t
mask
;
double
value
=
defaultBody
.
getFloat64
Value
();
double
value
=
defaultBody
.
getFloat64
();
static_assert
(
sizeof
(
mask
)
==
sizeof
(
value
),
"bug"
);
memcpy
(
&
mask
,
&
value
,
sizeof
(
mask
));
defaultMask
=
kj
::
str
(
mask
,
"ull"
);
}
break
;
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
case
schema
2
:
:
Type
::
TEXT
:
kind
=
FieldKind
::
BLOB
;
if
(
defaultBody
.
hasText
Value
())
{
defaultOffset
=
member
.
getDefaultValueSchemaOffset
();
defaultSize
=
defaultBody
.
getText
Value
().
size
();
if
(
defaultBody
.
hasText
())
{
defaultOffset
=
field
.
getDefaultValueSchemaOffset
();
defaultSize
=
defaultBody
.
getText
().
size
();
}
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
case
schema
2
:
:
Type
::
DATA
:
kind
=
FieldKind
::
BLOB
;
if
(
defaultBody
.
hasData
Value
())
{
defaultOffset
=
member
.
getDefaultValueSchemaOffset
();
defaultSize
=
defaultBody
.
getData
Value
().
size
();
if
(
defaultBody
.
hasData
())
{
defaultOffset
=
field
.
getDefaultValueSchemaOffset
();
defaultSize
=
defaultBody
.
getData
().
size
();
}
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
case
schema
2
:
:
Type
::
ENUM
:
kind
=
FieldKind
::
PRIMITIVE
;
if
(
defaultBody
.
getEnum
Value
()
!=
0
)
{
defaultMask
=
kj
::
str
(
defaultBody
.
getEnum
Value
(),
"u"
);
if
(
defaultBody
.
getEnum
()
!=
0
)
{
defaultMask
=
kj
::
str
(
defaultBody
.
getEnum
(),
"u"
);
}
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
case
schema
2
:
:
Type
::
STRUCT
:
kind
=
FieldKind
::
STRUCT
;
if
(
defaultBody
.
hasStruct
Value
())
{
defaultOffset
=
member
.
getDefaultValueSchemaOffset
();
if
(
defaultBody
.
hasStruct
())
{
defaultOffset
=
field
.
getDefaultValueSchemaOffset
();
}
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
case
schema
2
:
:
Type
::
LIST
:
kind
=
FieldKind
::
LIST
;
if
(
defaultBody
.
hasList
Value
())
{
defaultOffset
=
member
.
getDefaultValueSchemaOffset
();
if
(
defaultBody
.
hasList
())
{
defaultOffset
=
field
.
getDefaultValueSchemaOffset
();
}
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYP
E
:
case
schema
2
:
:
Type
::
INTERFAC
E
:
kind
=
FieldKind
::
INTERFACE
;
break
;
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
case
schema
2
:
:
Type
::
OBJECT
:
kind
=
FieldKind
::
OBJECT
;
if
(
defaultBody
.
hasObject
Value
())
{
defaultOffset
=
member
.
getDefaultValueSchemaOffset
();
if
(
defaultBody
.
hasObject
())
{
defaultOffset
=
field
.
getDefaultValueSchemaOffset
();
}
break
;
}
...
...
@@ -483,14 +430,7 @@ private:
defaultMaskParam
=
kj
::
str
(
", "
,
defaultMask
);
}
kj
::
String
titleCase
=
toTitleCase
(
proto
.
getName
());
DiscriminantChecks
unionDiscrim
;
KJ_IF_MAYBE
(
u
,
member
.
getContainingUnion
())
{
unionDiscrim
=
makeDiscriminantChecks
(
scope
,
proto
.
getName
(),
*
u
);
}
uint
offset
=
field
.
getOffset
();
uint
offset
=
regularField
.
getOffset
();
if
(
kind
==
FieldKind
::
PRIMITIVE
)
{
return
FieldText
{
...
...
@@ -635,7 +575,7 @@ private:
}
else
{
// Blob, struct, or list. These have only minor differences.
uint64_t
typeId
=
member
.
getContainingStruct
().
getProto
().
getId
();
uint64_t
typeId
=
field
.
getContainingStruct
().
getProto
().
getId
();
kj
::
String
defaultParam
=
defaultOffset
==
0
?
kj
::
str
()
:
kj
::
str
(
",
\n
::capnp::schemas::s_"
,
kj
::
hex
(
typeId
),
".encodedNode + "
,
defaultOffset
,
defaultSize
==
0
?
kj
::
strTree
()
:
kj
::
strTree
(
", "
,
defaultSize
));
...
...
@@ -644,38 +584,38 @@ private:
bool
isStructList
=
false
;
if
(
kind
==
FieldKind
::
LIST
)
{
bool
primitiveElement
=
false
;
switch
(
typeBody
.
getList
Type
().
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
switch
(
typeBody
.
getList
().
which
())
{
case
schema
2
:
:
Type
::
VOID
:
case
schema
2
:
:
Type
::
BOOL
:
case
schema
2
:
:
Type
::
INT8
:
case
schema
2
:
:
Type
::
INT16
:
case
schema
2
:
:
Type
::
INT32
:
case
schema
2
:
:
Type
::
INT64
:
case
schema
2
:
:
Type
::
UINT8
:
case
schema
2
:
:
Type
::
UINT16
:
case
schema
2
:
:
Type
::
UINT32
:
case
schema
2
:
:
Type
::
UINT64
:
case
schema
2
:
:
Type
::
FLOAT32
:
case
schema
2
:
:
Type
::
FLOAT64
:
case
schema
2
:
:
Type
::
ENUM
:
primitiveElement
=
true
;
break
;
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
case
schema
:
:
Type
::
Body
::
INTERFACE_TYP
E
:
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
case
schema
2
:
:
Type
::
TEXT
:
case
schema
2
:
:
Type
::
DATA
:
case
schema
2
:
:
Type
::
LIST
:
case
schema
2
:
:
Type
::
INTERFAC
E
:
case
schema
2
:
:
Type
::
OBJECT
:
primitiveElement
=
false
;
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
case
schema
2
:
:
Type
::
STRUCT
:
isStructList
=
true
;
primitiveElement
=
false
;
break
;
}
elementReaderType
=
kj
::
str
(
typeName
(
typeBody
.
getList
Type
()),
typeName
(
typeBody
.
getList
()),
primitiveElement
?
""
:
"::Reader"
);
}
...
...
@@ -766,7 +706,7 @@ private:
// -----------------------------------------------------------------
kj
::
StringTree
makeReaderDef
(
kj
::
StringPtr
fullName
,
kj
::
StringPtr
unqualifiedParentType
,
kj
::
StringPtr
stringifier
,
kj
::
StringTree
&&
methodDecls
)
{
bool
isUnion
,
kj
::
Array
<
kj
::
StringTree
>
&&
methodDecls
)
{
return
kj
::
strTree
(
"class "
,
fullName
,
"::Reader {
\n
"
"public:
\n
"
...
...
@@ -779,6 +719,7 @@ private:
" return _reader.totalSize() / ::capnp::WORDS;
\n
"
" }
\n
"
"
\n
"
,
isUnion
?
kj
::
strTree
(
" inline Which which() const;
\n
"
)
:
kj
::
strTree
(),
kj
::
mv
(
methodDecls
),
"private:
\n
"
" ::capnp::_::StructReader _reader;
\n
"
...
...
@@ -792,16 +733,15 @@ private:
" friend class ::capnp::Orphanage;
\n
"
" friend ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Reader reader);
\n
"
"};
\n
"
"
\n
"
,
stringifier
.
size
()
>
0
?
kj
::
strTree
(
"inline ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Reader reader) {
\n
"
" return ::capnp::_::"
,
stringifier
,
"<"
,
fullName
,
">(reader._reader);
\n
"
"}
\n
"
"
\n
"
)
:
kj
::
strTree
());
"
\n
"
"inline ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Reader reader) {
\n
"
" return ::capnp::_::structString<"
,
fullName
,
">(reader._reader);
\n
"
"}
\n
"
"
\n
"
);
}
kj
::
StringTree
makeBuilderDef
(
kj
::
StringPtr
fullName
,
kj
::
StringPtr
unqualifiedParentType
,
kj
::
StringPtr
stringifier
,
kj
::
StringTree
&&
methodDecls
)
{
bool
isUnion
,
kj
::
Array
<
kj
::
StringTree
>
&&
methodDecls
)
{
return
kj
::
strTree
(
"class "
,
fullName
,
"::Builder {
\n
"
"public:
\n
"
...
...
@@ -814,6 +754,7 @@ private:
"
\n
"
" inline size_t totalSizeInWords() { return asReader().totalSizeInWords(); }
\n
"
"
\n
"
,
isUnion
?
kj
::
strTree
(
" inline Which which();
\n
"
)
:
kj
::
strTree
(),
kj
::
mv
(
methodDecls
),
"private:
\n
"
" ::capnp::_::StructBuilder _builder;
\n
"
...
...
@@ -822,235 +763,11 @@ private:
" friend class ::capnp::Orphanage;
\n
"
" friend ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Builder builder);
\n
"
"};
\n
"
"
\n
"
,
stringifier
.
size
()
>
0
?
kj
::
strTree
(
"inline ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Builder builder) {
\n
"
" return ::capnp::_::"
,
stringifier
,
"<"
,
fullName
,
">(builder._builder.asReader());
\n
"
"}
\n
"
"
\n
"
)
:
kj
::
strTree
());
}
// -----------------------------------------------------------------
struct
MembersText
{
kj
::
StringTree
innerTypeDecls
;
kj
::
StringTree
innerTypeDefs
;
kj
::
StringTree
innerTypeReaderBuilderDefs
;
kj
::
StringTree
readerMethodDecls
;
kj
::
StringTree
builderMethodDecls
;
kj
::
StringTree
inlineMethodDefs
;
kj
::
StringTree
capnpPrivateDecls
;
kj
::
StringTree
capnpPrivateDefs
;
};
MembersText
makeMemberText
(
kj
::
StringPtr
namespace_
,
kj
::
StringPtr
containingType
,
StructSchema
::
Member
member
)
{
auto
proto
=
member
.
getProto
();
switch
(
proto
.
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
{
auto
fieldText
=
makeFieldText
(
kj
::
str
(
containingType
,
"::"
),
member
.
asField
());
return
MembersText
{
kj
::
strTree
(),
kj
::
strTree
(),
kj
::
strTree
(),
kj
::
mv
(
fieldText
.
readerMethodDecls
),
kj
::
mv
(
fieldText
.
builderMethodDecls
),
kj
::
mv
(
fieldText
.
inlineMethodDefs
),
kj
::
strTree
(),
kj
::
strTree
(),
};
}
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
{
auto
subMembers
=
member
.
asUnion
().
getMembers
();
auto
unionName
=
proto
.
getName
();
uint
discrimOffset
=
proto
.
getBody
().
getUnionMember
().
getDiscriminantOffset
();
auto
whichEnumDef
=
kj
::
strTree
(
" enum Which: uint16_t {
\n
"
,
KJ_MAP
(
subMembers
,
subMember
)
{
return
kj
::
strTree
(
" "
,
toUpperCase
(
subMember
.
getProto
().
getName
()),
",
\n
"
);
},
" };
\n
"
);
if
(
unionName
.
size
()
==
0
)
{
// Anonymous union.
auto
subText
=
makeMembersText
(
namespace_
,
containingType
,
subMembers
);
return
MembersText
{
kj
::
strTree
(
kj
::
mv
(
whichEnumDef
),
kj
::
mv
(
subText
.
innerTypeDecls
)),
kj
::
mv
(
subText
.
innerTypeDefs
),
kj
::
mv
(
subText
.
innerTypeReaderBuilderDefs
),
kj
::
strTree
(
" inline Which which() const;
\n
"
,
kj
::
mv
(
subText
.
readerMethodDecls
)),
kj
::
strTree
(
" inline Which which();
\n
"
,
kj
::
mv
(
subText
.
builderMethodDecls
)),
kj
::
strTree
(
"inline "
,
containingType
,
"::Which "
,
containingType
,
"::Reader::which() const {
\n
"
" return _reader.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"inline "
,
containingType
,
"::Which "
,
containingType
,
"::Builder::which() {
\n
"
" return _builder.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"
\n
"
,
kj
::
mv
(
subText
.
inlineMethodDefs
)),
kj
::
mv
(
subText
.
capnpPrivateDecls
),
kj
::
mv
(
subText
.
capnpPrivateDefs
),
};
}
else
{
// Named union.
auto
titleCase
=
toTitleCase
(
unionName
);
auto
fullName
=
kj
::
str
(
containingType
,
"::"
,
titleCase
);
auto
subText
=
makeMembersText
(
namespace_
,
fullName
,
subMembers
);
return
MembersText
{
kj
::
strTree
(
" struct "
,
titleCase
,
";
\n
"
),
kj
::
strTree
(
"struct "
,
fullName
,
" {
\n
"
" "
,
titleCase
,
"() = delete;
\n
"
" class Reader;
\n
"
" class Builder;
\n
"
"
\n
"
,
kj
::
mv
(
whichEnumDef
),
kj
::
mv
(
subText
.
innerTypeDecls
),
"};
\n
"
"
\n
"
,
kj
::
mv
(
subText
.
innerTypeDefs
)),
kj
::
strTree
(
makeReaderDef
(
fullName
,
titleCase
,
"unionString"
,
kj
::
strTree
(
" inline Which which() const;
\n
"
,
kj
::
mv
(
subText
.
readerMethodDecls
))),
makeBuilderDef
(
fullName
,
titleCase
,
"unionString"
,
kj
::
strTree
(
" inline Which which();
\n
"
,
kj
::
mv
(
subText
.
builderMethodDecls
))),
kj
::
mv
(
subText
.
innerTypeReaderBuilderDefs
)),
kj
::
strTree
(
" inline "
,
titleCase
,
"::Reader get"
,
titleCase
,
"() const;
\n
"
),
kj
::
strTree
(
" inline "
,
titleCase
,
"::Builder get"
,
titleCase
,
"();
\n
"
),
kj
::
strTree
(
"inline "
,
fullName
,
"::Reader "
,
containingType
,
"::Reader::get"
,
titleCase
,
"() const {
\n
"
" return "
,
fullName
,
"::Reader(_reader);
\n
"
"}
\n
"
"inline "
,
fullName
,
"::Builder "
,
containingType
,
"::Builder::get"
,
titleCase
,
"() {
\n
"
" return "
,
fullName
,
"::Builder(_builder);
\n
"
"}
\n
"
"inline "
,
fullName
,
"::Which "
,
fullName
,
"::Reader::which() const {
\n
"
" return _reader.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"inline "
,
fullName
,
"::Which "
,
fullName
,
"::Builder::which() {
\n
"
" return _builder.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"
\n
"
,
kj
::
mv
(
subText
.
inlineMethodDefs
)),
kj
::
strTree
(
"CAPNP_DECLARE_UNION(
\n
"
" "
,
namespace_
,
"::"
,
fullName
,
",
\n
"
" "
,
namespace_
,
"::"
,
containingType
,
", "
,
member
.
getIndex
(),
");
\n
"
,
kj
::
mv
(
subText
.
capnpPrivateDecls
)),
kj
::
strTree
(
"CAPNP_DEFINE_UNION(
\n
"
" "
,
namespace_
,
"::"
,
fullName
,
");
\n
"
,
kj
::
mv
(
subText
.
capnpPrivateDefs
)),
};
}
}
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
{
auto
titleCase
=
toTitleCase
(
proto
.
getName
());
auto
fullName
=
kj
::
str
(
containingType
,
"::"
,
titleCase
);
auto
subText
=
makeMembersText
(
namespace_
,
fullName
,
member
.
asGroup
().
getMembers
());
DiscriminantChecks
unionDiscrim
;
KJ_IF_MAYBE
(
u
,
member
.
getContainingUnion
())
{
unionDiscrim
=
makeDiscriminantChecks
(
kj
::
str
(
containingType
,
"::"
),
proto
.
getName
(),
*
u
);
}
return
MembersText
{
kj
::
strTree
(
" struct "
,
titleCase
,
";
\n
"
),
kj
::
strTree
(
"struct "
,
containingType
,
"::"
,
titleCase
,
" {
\n
"
" "
,
titleCase
,
"() = delete;
\n
"
"
\n
"
,
" class Reader;
\n
"
" class Builder;
\n
"
,
kj
::
mv
(
subText
.
innerTypeDecls
),
"};
\n
"
"
\n
"
,
kj
::
mv
(
subText
.
innerTypeDefs
)),
kj
::
strTree
(
makeReaderDef
(
fullName
,
titleCase
,
""
,
kj
::
mv
(
subText
.
readerMethodDecls
)),
makeBuilderDef
(
fullName
,
titleCase
,
""
,
kj
::
mv
(
subText
.
builderMethodDecls
)),
kj
::
mv
(
subText
.
innerTypeReaderBuilderDefs
)),
kj
::
strTree
(
" inline "
,
titleCase
,
"::Reader get"
,
titleCase
,
"() const;
\n
"
),
kj
::
strTree
(
" inline "
,
titleCase
,
"::Builder get"
,
titleCase
,
"();
\n
"
" inline "
,
titleCase
,
"::Builder init"
,
titleCase
,
"();
\n
"
),
kj
::
strTree
(
"inline "
,
fullName
,
"::Reader "
,
containingType
,
"::Reader::get"
,
titleCase
,
"() const {
\n
"
,
unionDiscrim
.
check
,
" return "
,
fullName
,
"::Reader(_reader);
\n
"
"}
\n
"
"inline "
,
fullName
,
"::Builder "
,
containingType
,
"::Builder::get"
,
titleCase
,
"() {
\n
"
,
unionDiscrim
.
check
,
" return "
,
fullName
,
"::Builder(_builder);
\n
"
"}
\n
"
// TODO(soon): This should really zero out the existing group. Maybe unions should
// support zeroing out the whole union?
"inline "
,
fullName
,
"::Builder "
,
containingType
,
"::Builder::init"
,
titleCase
,
"() {
\n
"
,
unionDiscrim
.
set
,
" return "
,
fullName
,
"::Builder(_builder);
\n
"
"}
\n
"
,
kj
::
mv
(
subText
.
inlineMethodDefs
)),
kj
::
mv
(
subText
.
capnpPrivateDecls
),
kj
::
mv
(
subText
.
capnpPrivateDefs
),
};
}
}
KJ_UNREACHABLE
;
}
MembersText
makeMembersText
(
kj
::
StringPtr
namespace_
,
kj
::
StringPtr
containingType
,
StructSchema
::
MemberList
members
)
{
auto
memberTexts
=
KJ_MAP
(
members
,
member
)
{
return
makeMemberText
(
namespace_
,
containingType
,
member
);
};
return
MembersText
{
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
innerTypeDecls
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
innerTypeDefs
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
innerTypeReaderBuilderDefs
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
readerMethodDecls
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
builderMethodDecls
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
inlineMethodDefs
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
capnpPrivateDecls
);
}),
kj
::
strTree
(
KJ_MAP
(
memberTexts
,
m
)
{
return
kj
::
mv
(
m
.
capnpPrivateDefs
);
}),
};
"
\n
"
"inline ::kj::StringTree KJ_STRINGIFY("
,
fullName
,
"::Builder builder) {
\n
"
" return ::capnp::_::structString<"
,
fullName
,
">(builder._builder.asReader());
\n
"
"}
\n
"
"
\n
"
);
}
// -----------------------------------------------------------------
...
...
@@ -1071,14 +788,27 @@ private:
auto
proto
=
schema
.
getProto
();
auto
fullName
=
kj
::
str
(
scope
,
name
);
auto
subScope
=
kj
::
str
(
fullName
,
"::"
);
auto
nestedTexts
=
KJ_MAP
(
proto
.
getNestedNodes
(),
nested
)
{
return
makeNodeText
(
namespace_
,
subScope
,
nested
.
getName
(),
schemaLoader
.
get
(
nested
.
getId
()));
};
auto
hexId
=
kj
::
hex
(
proto
.
getId
());
kj
::
ArrayPtr
<
const
word
>
rawSchema
=
schema
.
asUncheckedMessage
();
// Compute nested nodes, including groups.
kj
::
Vector
<
NodeText
>
nestedTexts
(
proto
.
getNestedNodes
().
size
());
for
(
auto
nested
:
proto
.
getNestedNodes
())
{
nestedTexts
.
add
(
makeNodeText
(
namespace_
,
subScope
,
nested
.
getName
(),
schemaLoader
.
get
(
nested
.
getId
())));
};
if
(
proto
.
which
()
==
schema2
::
Node
::
STRUCT
)
{
for
(
auto
field
:
proto
.
getStruct
().
getFields
())
{
if
(
field
.
which
()
==
schema2
::
Field
::
GROUP
)
{
nestedTexts
.
add
(
makeNodeText
(
namespace_
,
subScope
,
toTitleCase
(
field
.
getName
()),
schemaLoader
.
get
(
field
.
getGroup
())));
}
}
}
// Convert the encoded schema to a literal byte array.
kj
::
ArrayPtr
<
const
word
>
rawSchema
=
schema
.
asUncheckedMessage
();
auto
schemaLiteral
=
kj
::
StringTree
(
KJ_MAP
(
rawSchema
,
w
)
{
const
byte
*
bytes
=
reinterpret_cast
<
const
byte
*>
(
&
w
);
...
...
@@ -1094,16 +824,16 @@ private:
std
::
set
<
uint64_t
>
deps
;
enumerateDeps
(
proto
,
deps
);
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>
memberInfos
;
switch
(
proto
.
getBody
().
which
())
{
case
schema
:
:
Node
::
Body
::
STRUCT_NODE
:
m
akeMemberInfoTable
(
0
,
schema
.
asStruct
().
getMembers
(),
memberInfos
);
kj
::
Array
<
uint
>
membersByName
;
switch
(
proto
.
which
())
{
case
schema
2
:
:
Node
::
STRUCT
:
m
embersByName
=
makeMembersByName
(
schema
.
asStruct
().
getFields
()
);
break
;
case
schema
:
:
Node
::
Body
::
ENUM_NODE
:
m
akeMemberInfoTable
(
0
,
schema
.
asEnum
().
getEnumerants
(),
memberInfos
);
case
schema
2
:
:
Node
::
ENUM
:
m
embersByName
=
makeMembersByName
(
schema
.
asEnum
().
getEnumerants
()
);
break
;
case
schema
:
:
Node
::
Body
::
INTERFACE_NOD
E
:
m
akeMemberInfoTable
(
0
,
schema
.
asInterface
().
getMethods
(),
memberInfos
);
case
schema
2
:
:
Node
::
INTERFAC
E
:
m
embersByName
=
makeMembersByName
(
schema
.
asInterface
().
getMethods
()
);
break
;
default:
break
;
...
...
@@ -1119,51 +849,66 @@ private:
},
"};
\n
"
"static const ::capnp::_::RawSchema::MemberInfo m_"
,
hexId
,
"[] = {
\n
"
,
KJ_MAP
(
memberInfos
,
info
)
{
return
kj
::
strTree
(
" { "
,
info
.
scopeOrdinal
,
", "
,
info
.
index
,
" },
\n
"
);
},
kj
::
StringTree
(
KJ_MAP
(
membersByName
,
index
)
{
return
kj
::
strTree
(
index
);
},
", "
),
"};
\n
"
"const ::capnp::_::RawSchema s_"
,
hexId
,
" = {
\n
"
" 0x"
,
hexId
,
", b_"
,
hexId
,
".words, "
,
rawSchema
.
size
(),
", d_"
,
hexId
,
", m_"
,
hexId
,
",
\n
"
" "
,
deps
.
size
(),
", "
,
member
Infos
.
size
(),
", nullptr, nullptr
\n
"
" "
,
deps
.
size
(),
", "
,
member
sByName
.
size
(),
", nullptr, nullptr
\n
"
"};
\n
"
);
switch
(
proto
.
getBody
().
which
())
{
case
schema
:
:
Node
::
Body
::
FILE_NOD
E
:
switch
(
proto
.
which
())
{
case
schema
2
:
:
Node
::
FIL
E
:
KJ_FAIL_REQUIRE
(
"This method shouldn't be called on file nodes."
);
case
schema
:
:
Node
::
Body
::
STRUCT_NODE
:
{
auto
membersText
=
makeMembersText
(
namespace_
,
fullName
,
schema
.
asStruct
().
getMembers
());
case
schema2
:
:
Node
::
STRUCT
:
{
auto
fieldTexts
=
KJ_MAP
(
schema
.
asStruct
().
getFields
(),
f
)
{
return
makeFieldText
(
subScope
,
f
);
};
auto
structNode
=
proto
.
getBody
().
getStructNode
();
auto
structNode
=
proto
.
getStruct
();
uint
discrimOffset
=
structNode
.
getDiscriminantOffset
();
return
NodeText
{
kj
::
strTree
(
" struct "
,
name
,
";
\n
"
),
kj
::
strTree
(
"struct "
,
scope
,
n
ame
,
" {
\n
"
,
"struct "
,
fullN
ame
,
" {
\n
"
,
" "
,
name
,
"() = delete;
\n
"
"
\n
"
" class Reader;
\n
"
" class Builder;
\n
"
,
kj
::
mv
(
membersText
.
innerTypeDecls
),
structNode
.
getDiscriminantCount
()
==
0
?
kj
::
strTree
()
:
kj
::
strTree
(
" enum Which: uint16_t {
\n
"
,
KJ_MAP
(
structNode
.
getFields
(),
f
)
{
if
(
f
.
hasDiscriminantValue
())
{
return
kj
::
strTree
(
" "
,
toUpperCase
(
f
.
getName
()),
",
\n
"
);
}
else
{
return
kj
::
strTree
();
}
},
" };
\n
"
),
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
outerTypeDecl
);
},
"};
\n
"
"
\n
"
,
kj
::
mv
(
membersText
.
innerTypeDefs
),
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
outerTypeDef
);
}),
kj
::
strTree
(
makeReaderDef
(
fullName
,
name
,
"structString"
,
kj
::
mv
(
membersText
.
readerMethodDecls
)),
makeBuilderDef
(
fullName
,
name
,
"structString"
,
kj
::
mv
(
membersText
.
builderMethodDecls
)),
kj
::
mv
(
membersText
.
innerTypeReaderBuilderDefs
),
makeReaderDef
(
fullName
,
name
,
structNode
.
getDiscriminantCount
()
!=
0
,
KJ_MAP
(
fieldTexts
,
f
)
{
return
kj
::
mv
(
f
.
readerMethodDecls
);
}),
makeBuilderDef
(
fullName
,
name
,
structNode
.
getDiscriminantCount
()
!=
0
,
KJ_MAP
(
fieldTexts
,
f
)
{
return
kj
::
mv
(
f
.
builderMethodDecls
);
}),
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
readerBuilderDefs
);
}),
kj
::
strTree
(
kj
::
mv
(
membersText
.
inlineMethodDefs
),
structNode
.
getDiscriminantCount
()
==
0
?
kj
::
strTree
()
:
kj
::
strTree
(
"inline "
,
fullName
,
"::Which "
,
fullName
,
"::Reader::which() const {
\n
"
" return _reader.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"inline "
,
fullName
,
"::Which "
,
fullName
,
"::Builder::which() {
\n
"
" return _builder.getDataField<Which>("
,
discrimOffset
,
" * ::capnp::ELEMENTS);
\n
"
"}
\n
"
"
\n
"
),
KJ_MAP
(
fieldTexts
,
f
)
{
return
kj
::
mv
(
f
.
inlineMethodDefs
);
},
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
inlineMethodDefs
);
}),
kj
::
strTree
(
...
...
@@ -1181,18 +926,16 @@ private:
structNode
.
getPointerSectionSize
(),
", "
,
FIELD_SIZE_NAMES
[
static_cast
<
uint
>
(
structNode
.
getPreferredListEncoding
())],
");
\n
"
,
kj
::
mv
(
membersText
.
capnpPrivateDecls
),
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
capnpPrivateDecls
);
}),
kj
::
strTree
(
"CAPNP_DEFINE_STRUCT(
\n
"
" "
,
namespace_
,
"::"
,
fullName
,
");
\n
"
,
kj
::
mv
(
membersText
.
capnpPrivateDefs
),
KJ_MAP
(
nestedTexts
,
n
)
{
return
kj
::
mv
(
n
.
capnpPrivateDefs
);
}),
};
}
case
schema
:
:
Node
::
Body
::
ENUM_NODE
:
{
case
schema
2
:
:
Node
::
ENUM
:
{
auto
enumerants
=
schema
.
asEnum
().
getEnumerants
();
return
NodeText
{
...
...
@@ -1227,7 +970,7 @@ private:
};
}
case
schema
:
:
Node
::
Body
::
INTERFACE_NOD
E
:
{
case
schema
2
:
:
Node
::
INTERFAC
E
:
{
return
NodeText
{
kj
::
strTree
(),
kj
::
strTree
(),
...
...
@@ -1246,7 +989,7 @@ private:
};
}
case
schema
:
:
Node
::
Body
::
CONST_NODE
:
{
case
schema
2
:
:
Node
::
CONST
:
{
return
NodeText
{
kj
::
strTree
(),
kj
::
strTree
(),
...
...
@@ -1261,7 +1004,7 @@ private:
};
}
case
schema
:
:
Node
::
Body
::
ANNOTATION_NODE
:
{
case
schema
2
:
:
Node
::
ANNOTATION
:
{
return
NodeText
{
kj
::
strTree
(),
kj
::
strTree
(),
...
...
@@ -1287,7 +1030,8 @@ private:
kj
::
StringTree
source
;
};
FileText
makeFileText
(
Schema
schema
)
{
FileText
makeFileText
(
Schema
schema
,
schema2
::
CodeGeneratorRequest
::
RequestedFile
::
Reader
request
)
{
usedImports
.
clear
();
auto
node
=
schema
.
getProto
();
...
...
@@ -1298,7 +1042,7 @@ private:
for
(
auto
annotation
:
node
.
getAnnotations
())
{
if
(
annotation
.
getId
()
==
NAMESPACE_ANNOTATION_ID
)
{
kj
::
StringPtr
ns
=
annotation
.
getValue
().
get
Body
().
getTextValue
();
kj
::
StringPtr
ns
=
annotation
.
getValue
().
get
Text
();
kj
::
StringPtr
ns2
=
ns
;
namespacePrefix
=
kj
::
str
(
"::"
,
ns
);
...
...
@@ -1327,7 +1071,7 @@ private:
kj
::
String
separator
=
kj
::
str
(
"// "
,
kj
::
repeat
(
'='
,
87
),
"
\n
"
);
kj
::
Vector
<
kj
::
StringPtr
>
includes
;
for
(
auto
import
:
node
.
getBody
().
getFileNode
()
.
getImports
())
{
for
(
auto
import
:
request
.
getImports
())
{
if
(
usedImports
.
count
(
import
.
getId
())
>
0
)
{
includes
.
add
(
import
.
getName
());
}
...
...
@@ -1430,7 +1174,7 @@ private:
ReaderOptions
options
;
options
.
traversalLimitInWords
=
1
<<
30
;
// Don't limit.
StreamFdMessageReader
reader
(
STDIN_FILENO
,
options
);
auto
request
=
reader
.
getRoot
<
schema
::
CodeGeneratorRequest
>
();
auto
request
=
reader
.
getRoot
<
schema
2
::
CodeGeneratorRequest
>
();
for
(
auto
node
:
request
.
getNodes
())
{
schemaLoader
.
load
(
node
);
...
...
@@ -1439,9 +1183,9 @@ private:
kj
::
FdOutputStream
rawOut
(
STDOUT_FILENO
);
kj
::
BufferedOutputStreamWrapper
out
(
rawOut
);
for
(
auto
fileId
:
request
.
getRequestedFiles
())
{
auto
schema
=
schemaLoader
.
get
(
fileId
);
auto
fileText
=
makeFileText
(
schema
);
for
(
auto
requestedFile
:
request
.
getRequestedFiles
())
{
auto
schema
=
schemaLoader
.
get
(
requestedFile
.
getId
()
);
auto
fileText
=
makeFileText
(
schema
,
requestedFile
);
writeFile
(
kj
::
str
(
schema
.
getProto
().
getDisplayName
(),
".h"
),
fileText
.
header
);
writeFile
(
kj
::
str
(
schema
.
getProto
().
getDisplayName
(),
".c++"
),
fileText
.
source
);
...
...
c++/src/capnp/compiler/node-translator.c++
View file @
0c7c610c
...
...
@@ -810,10 +810,7 @@ public:
}
schema2
::
Field
::
Builder
fieldBuilder
=
member
.
getSchema
();
fieldBuilder
.
setName
(
member
.
decl
.
getName
().
getValue
());
fieldBuilder
.
getOrdinal
().
setExplicit
(
entry
.
first
);
fieldBuilder
.
setCodeOrder
(
member
.
codeOrder
);
switch
(
member
.
decl
.
getBody
().
which
())
{
case
Declaration
:
:
Body
::
FIELD_DECL
:
{
...
...
@@ -891,7 +888,7 @@ public:
// OK, we should have built all the members. Now go through and make sure the discriminant
// offsets have been copied over to the schemas and annotations have been applied.
root
.
setDiscriminantOffsetInSchema
();
root
.
finishGroup
();
for
(
auto
member
:
allMembers
)
{
kj
::
StringPtr
targetsFlagName
;
switch
(
member
->
decl
.
getBody
().
which
())
{
...
...
@@ -900,13 +897,12 @@ public:
break
;
case
Declaration
:
:
Body
::
UNION_DECL
:
member
->
setDiscriminantOffsetInSchema
();
member
->
finishGroup
();
targetsFlagName
=
"targetsUnion"
;
break
;
case
Declaration
:
:
Body
::
GROUP_DECL
:
member
->
setDiscriminantOffsetInSchema
();
// in case it contains an unnamed union
member
->
node
.
setId
(
generateGroupId
(
member
->
parent
->
node
.
getId
(),
member
->
index
));
member
->
finishGroup
();
targetsFlagName
=
"targetsGroup"
;
break
;
...
...
@@ -1026,6 +1022,8 @@ private:
if
(
isInUnion
)
{
builder
.
setDiscriminantValue
(
parent
->
unionDiscriminantCount
++
);
}
builder
.
setName
(
decl
.
getName
().
getValue
());
builder
.
setCodeOrder
(
codeOrder
);
schema
=
builder
;
return
builder
;
}
...
...
@@ -1039,20 +1037,28 @@ private:
auto
structNode
=
node
.
getStruct
();
if
(
!
structNode
.
hasFields
())
{
getSchema
();
// Make sure field exists in parent once the first child is added.
if
(
parent
!=
nullptr
)
{
getSchema
();
// Make sure field exists in parent once the first child is added.
}
return
structNode
.
initFields
(
childCount
)[
childInitializedCount
++
];
}
else
{
return
structNode
.
getFields
()[
childInitializedCount
++
];
}
}
void
setDiscriminantOffsetInSchema
()
{
void
finishGroup
()
{
if
(
unionScope
!=
nullptr
)
{
unionScope
->
addDiscriminant
();
// if it hasn't happened already
auto
structNode
=
node
.
getStruct
();
structNode
.
setDiscriminantCount
(
unionDiscriminantCount
);
structNode
.
setDiscriminantOffset
(
KJ_ASSERT_NONNULL
(
unionScope
->
discriminantOffset
));
}
if
(
parent
!=
nullptr
)
{
uint64_t
groupId
=
generateGroupId
(
parent
->
node
.
getId
(),
index
);
node
.
setId
(
groupId
);
getSchema
().
setGroup
(
groupId
);
}
}
};
...
...
@@ -1064,9 +1070,7 @@ private:
// All members, including ones that don't have ordinals.
void
traverseUnion
(
List
<
Declaration
>::
Reader
members
,
MemberInfo
&
parent
,
StructLayout
::
Union
&
layout
)
{
uint
codeOrder
=
0
;
StructLayout
::
Union
&
layout
,
uint
&
codeOrder
)
{
if
(
members
.
size
()
<
2
)
{
errorReporter
.
addErrorOn
(
parent
.
decl
,
"Union must have at least two members."
);
}
...
...
@@ -1145,8 +1149,11 @@ private:
case
Declaration
:
:
Body
::
UNION_DECL
:
{
StructLayout
::
Union
&
unionLayout
=
arena
.
allocate
<
StructLayout
::
Union
>
(
layout
);
uint
independentSubCodeOrder
=
0
;
uint
*
subCodeOrder
=
&
independentSubCodeOrder
;
if
(
member
.
getName
().
getValue
()
==
""
)
{
memberInfo
=
&
parent
;
subCodeOrder
=
&
codeOrder
;
}
else
{
parent
.
childCount
++
;
memberInfo
=
&
arena
.
allocate
<
MemberInfo
>
(
...
...
@@ -1156,7 +1163,7 @@ private:
allMembers
.
add
(
memberInfo
);
}
memberInfo
->
unionScope
=
&
unionLayout
;
traverseUnion
(
member
.
getNestedDecls
(),
*
memberInfo
,
unionLayout
);
traverseUnion
(
member
.
getNestedDecls
(),
*
memberInfo
,
unionLayout
,
*
subCodeOrder
);
if
(
member
.
getId
().
which
()
==
Declaration
::
Id
::
ORDINAL
)
{
ordinal
=
member
.
getId
().
getOrdinal
().
getValue
();
}
...
...
@@ -1517,8 +1524,17 @@ void NodeTranslator::compileValue(ValueExpression::Reader source, schema2::Type:
schema2
::
Value
::
Builder
target
,
bool
isBootstrap
)
{
#warning "temporary hack for schema transition"
switch
(
type
.
which
())
{
case
schema2
:
:
Type
::
TEXT
:
target
.
setText
(
source
.
getBody
().
getString
());
break
;
case
schema2
:
:
Type
::
UINT16
:
target
.
setUint16
(
source
.
getBody
().
getPositiveInt
());
break
;
default
:
KJ_FAIL_ASSERT
(
"Need to compile value type:"
,
(
uint
)
type
.
which
());
KJ_FAIL_ASSERT
(
"Need to compile value type:"
,
(
uint
)
type
.
which
(),
wipNode
.
getReader
().
getDisplayName
());
}
#if 0
...
...
c++/src/capnp/generated-header-support.h
View file @
0c7c610c
...
...
@@ -240,7 +240,8 @@ inline kj::StringTree structString(StructReader reader) {
template
<
typename
T
>
inline
kj
::
StringTree
unionString
(
StructReader
reader
)
{
return
unionString
(
reader
,
rawSchema
<
UnionParentType
<
T
>>
(),
unionMemberIndex
<
T
>
());
#warning "remove this"
return
kj
::
strTree
();
}
}
// namespace _ (private)
...
...
c++/src/capnp/schema-loader.c++
View file @
0c7c610c
...
...
@@ -71,7 +71,8 @@ public:
TryGetResult
tryGet
(
uint64_t
typeId
)
const
;
kj
::
Array
<
Schema
>
getAllLoaded
()
const
;
void
requireStructSize
(
uint64_t
id
,
uint
dataWordCount
,
uint
pointerCount
);
void
requireStructSize
(
uint64_t
id
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
);
// Require any struct nodes loaded with this ID -- in the past and in the future -- to have at
// least the given sizes. Struct nodes that don't comply will simply be rewritten to comply.
// This is used to ensure that parents of group nodes have at least the size of the group node,
...
...
@@ -86,6 +87,7 @@ private:
struct
RequiredSize
{
uint16_t
dataWordCount
;
uint16_t
pointerCount
;
schema2
::
ElementSize
preferredListEncoding
;
};
std
::
unordered_map
<
uint64_t
,
RequiredSize
>
structSizeRequirements
;
...
...
@@ -103,13 +105,15 @@ private:
// (but at least can't cause memory corruption).
kj
::
ArrayPtr
<
word
>
rewriteStructNodeWithSizes
(
schema2
::
Node
::
Reader
node
,
uint
dataWordCount
,
uint
pointerCount
);
schema2
::
Node
::
Reader
node
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
);
// Make a copy of the given node (which must be a struct node) and set its sizes to be the max
// of what it said already and the given sizes.
// If the encoded node does not meet the given struct size requirements, make a new copy that
// does.
void
applyStructSizeRequirement
(
_
::
RawSchema
*
raw
,
uint
dataWordCount
,
uint
pointerCount
);
void
applyStructSizeRequirement
(
_
::
RawSchema
*
raw
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
);
};
// =======================================================================================
...
...
@@ -340,7 +344,8 @@ private:
// Require that the group's scope has at least the same size as the group, so that anyone
// constructing an instance of the outer scope can safely read/write the group.
loader
.
requireStructSize
(
scopeId
,
structNode
.
getDataSectionWordSize
(),
structNode
.
getPointerSectionSize
());
structNode
.
getPointerSectionSize
(),
structNode
.
getPreferredListEncoding
());
// Require that the parent type is a struct.
validateTypeId
(
scopeId
,
schema2
::
Node
::
STRUCT
);
...
...
@@ -1131,7 +1136,8 @@ _::RawSchema* SchemaLoader::Impl::loadNative(const _::RawSchema* nativeSchema) {
auto
reqIter
=
structSizeRequirements
.
find
(
nativeSchema
->
id
);
if
(
reqIter
!=
structSizeRequirements
.
end
())
{
applyStructSizeRequirement
(
result
,
reqIter
->
second
.
dataWordCount
,
reqIter
->
second
.
pointerCount
);
reqIter
->
second
.
pointerCount
,
reqIter
->
second
.
preferredListEncoding
);
}
}
else
{
// The existing schema is newer.
...
...
@@ -1200,14 +1206,21 @@ kj::Array<Schema> SchemaLoader::Impl::getAllLoaded() const {
return
result
;
}
void
SchemaLoader
::
Impl
::
requireStructSize
(
uint64_t
id
,
uint
dataWordCount
,
uint
pointerCount
)
{
void
SchemaLoader
::
Impl
::
requireStructSize
(
uint64_t
id
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
)
{
auto
&
slot
=
structSizeRequirements
[
id
];
slot
.
dataWordCount
=
kj
::
max
(
slot
.
dataWordCount
,
dataWordCount
);
slot
.
pointerCount
=
kj
::
max
(
slot
.
pointerCount
,
pointerCount
);
if
(
slot
.
dataWordCount
+
slot
.
pointerCount
>=
2
)
{
slot
.
preferredListEncoding
=
schema2
::
ElementSize
::
INLINE_COMPOSITE
;
}
else
{
slot
.
preferredListEncoding
=
kj
::
max
(
slot
.
preferredListEncoding
,
preferredListEncoding
);
}
auto
iter
=
schemas
.
find
(
id
);
if
(
iter
!=
schemas
.
end
())
{
applyStructSizeRequirement
(
iter
->
second
,
dataWordCount
,
pointerCount
);
applyStructSizeRequirement
(
iter
->
second
,
dataWordCount
,
pointerCount
,
preferredListEncoding
);
}
}
...
...
@@ -1227,9 +1240,11 @@ kj::ArrayPtr<word> SchemaLoader::Impl::makeUncheckedNodeEnforcingSizeRequirement
auto
requirement
=
iter
->
second
;
auto
structNode
=
node
.
getStruct
();
if
(
structNode
.
getDataSectionWordSize
()
<
requirement
.
dataWordCount
||
structNode
.
getPointerSectionSize
()
<
requirement
.
pointerCount
)
{
structNode
.
getPointerSectionSize
()
<
requirement
.
pointerCount
||
structNode
.
getPreferredListEncoding
()
<
requirement
.
preferredListEncoding
)
{
return
rewriteStructNodeWithSizes
(
node
,
requirement
.
dataWordCount
,
requirement
.
pointerCount
);
requirement
.
pointerCount
,
requirement
.
preferredListEncoding
);
}
}
}
...
...
@@ -1238,7 +1253,8 @@ kj::ArrayPtr<word> SchemaLoader::Impl::makeUncheckedNodeEnforcingSizeRequirement
}
kj
::
ArrayPtr
<
word
>
SchemaLoader
::
Impl
::
rewriteStructNodeWithSizes
(
schema2
::
Node
::
Reader
node
,
uint
dataWordCount
,
uint
pointerCount
)
{
schema2
::
Node
::
Reader
node
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
)
{
MallocMessageBuilder
builder
;
builder
.
setRoot
(
node
);
...
...
@@ -1247,18 +1263,28 @@ kj::ArrayPtr<word> SchemaLoader::Impl::rewriteStructNodeWithSizes(
newStruct
.
setDataSectionWordSize
(
kj
::
max
(
newStruct
.
getDataSectionWordSize
(),
dataWordCount
));
newStruct
.
setPointerSectionSize
(
kj
::
max
(
newStruct
.
getPointerSectionSize
(),
pointerCount
));
if
(
newStruct
.
getDataSectionWordSize
()
+
newStruct
.
getPointerSectionSize
()
>=
2
)
{
newStruct
.
setPreferredListEncoding
(
schema2
::
ElementSize
::
INLINE_COMPOSITE
);
}
else
{
newStruct
.
setPreferredListEncoding
(
kj
::
max
(
newStruct
.
getPreferredListEncoding
(),
preferredListEncoding
));
}
return
makeUncheckedNode
(
root
);
}
void
SchemaLoader
::
Impl
::
applyStructSizeRequirement
(
_
::
RawSchema
*
raw
,
uint
dataWordCount
,
uint
pointerCount
)
{
_
::
RawSchema
*
raw
,
uint
dataWordCount
,
uint
pointerCount
,
schema2
::
ElementSize
preferredListEncoding
)
{
auto
node
=
readMessageUnchecked
<
schema2
::
Node
>
(
raw
->
encodedNode
);
auto
structNode
=
node
.
getStruct
();
if
(
structNode
.
getDataSectionWordSize
()
<
dataWordCount
||
structNode
.
getPointerSectionSize
()
<
pointerCount
)
{
structNode
.
getPointerSectionSize
()
<
pointerCount
||
structNode
.
getPreferredListEncoding
()
<
preferredListEncoding
)
{
// Sizes need to be increased. Must rewrite.
kj
::
ArrayPtr
<
word
>
words
=
rewriteStructNodeWithSizes
(
node
,
dataWordCount
,
pointerCount
);
kj
::
ArrayPtr
<
word
>
words
=
rewriteStructNodeWithSizes
(
node
,
dataWordCount
,
pointerCount
,
preferredListEncoding
);
// We don't need to re-validate the node because we know this change could not possibly have
// invalidated it. Just remake the unchecked message.
...
...
c++/src/capnp/schema.h
View file @
0c7c610c
...
...
@@ -154,8 +154,6 @@ private:
friend
class
Schema
;
friend
kj
::
StringTree
_
::
structString
(
_
::
StructReader
reader
,
const
_
::
RawSchema
&
schema
);
friend
kj
::
StringTree
_
::
unionString
(
_
::
StructReader
reader
,
const
_
::
RawSchema
&
schema
,
uint
fieldIndex
);
};
class
StructSchema
::
Field
{
...
...
c++/src/capnp/schema2.capnp
View file @
0c7c610c
...
...
@@ -42,7 +42,7 @@ struct Node {
# If you want a shorter version of `displayName` (just naming this node, without its surrounding
# scope), chop off this many characters from the beginning of `displayName`.
scopeId @3 :Id
= 0
;
scopeId @3 :Id;
# ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back
# at this node, but robust code should avoid relying on this (and, in fact, group nodes are not
# listed in the outer struct's nestedNodes, since they are listed in the fields). `scopeId` is
...
...
@@ -105,7 +105,8 @@ struct Node {
# `isGroup` = true.
discriminantOffset @12 :UInt32;
# If `isUnion` is true, this is the offset of the union discriminant, in multiples of 16 bits.
# If `discriminantCount` is non-zero, this is the offset of the union discriminant, in
# multiples of 16 bits.
fields @13 :List(Field);
# Fields defined within this scope (either the struct's top-level fields, or the fields of
...
...
c++/src/capnp/stringify.c++
View file @
0c7c610c
...
...
@@ -99,21 +99,19 @@ private:
}
};
schema
::
Type
::
Body
::
Which
whichMemberType
(
const
StructSchema
::
Member
&
member
)
{
auto
body
=
member
.
getProto
().
getBody
();
switch
(
body
.
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
return
schema
::
Type
::
Body
::
VOID_TYPE
;
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
return
schema
::
Type
::
Body
::
STRUCT_TYPE
;
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
return
body
.
getFieldMember
().
getType
().
getBody
().
which
();
static
schema2
::
Type
::
Which
whichFieldType
(
const
StructSchema
::
Field
&
field
)
{
auto
proto
=
field
.
getProto
();
switch
(
proto
.
which
())
{
case
schema2
:
:
Field
::
REGULAR
:
return
proto
.
getRegular
().
getType
().
which
();
case
schema2
:
:
Field
::
GROUP
:
return
schema2
::
Type
::
STRUCT
;
}
KJ_UNREACHABLE
;
}
static
kj
::
StringTree
print
(
const
DynamicValue
::
Reader
&
value
,
schema
::
Type
::
Body
::
Which
which
,
Indent
indent
,
schema
2
::
Type
::
Which
which
,
Indent
indent
,
PrintMode
mode
)
{
switch
(
value
.
getType
())
{
case
DynamicValue
:
:
UNKNOWN
:
...
...
@@ -127,7 +125,7 @@ static kj::StringTree print(const DynamicValue::Reader& value,
case
DynamicValue
:
:
UINT
:
return
kj
::
strTree
(
value
.
as
<
uint64_t
>
());
case
DynamicValue
:
:
FLOAT
:
if
(
which
==
schema
::
Type
::
Body
::
FLOAT32_TYPE
)
{
if
(
which
==
schema
2
::
Type
::
FLOAT32
)
{
return
kj
::
strTree
(
value
.
as
<
float
>
());
}
else
{
return
kj
::
strTree
(
value
.
as
<
double
>
());
...
...
@@ -192,40 +190,31 @@ static kj::StringTree print(const DynamicValue::Reader& value,
}
case
DynamicValue
:
:
STRUCT
:
{
auto
structValue
=
value
.
as
<
DynamicStruct
>
();
auto
memberSchemas
=
structValue
.
getSchema
().
getMembers
();
kj
::
Vector
<
kj
::
StringTree
>
printedMembers
(
memberSchemas
.
size
());
for
(
auto
member
:
memberSchemas
)
{
if
(
structValue
.
has
(
member
))
{
auto
name
=
member
.
getProto
().
getName
();
if
(
name
.
size
()
==
0
)
{
// Unnamed union. Just print the content.
printedMembers
.
add
(
kj
::
strTree
(
print
(
structValue
.
get
(
member
),
whichMemberType
(
member
),
indent
.
next
(),
BARE
)));
}
else
{
printedMembers
.
add
(
kj
::
strTree
(
name
,
" = "
,
print
(
structValue
.
get
(
member
),
whichMemberType
(
member
),
indent
.
next
(),
PREFIXED
)));
}
auto
unionFields
=
structValue
.
getSchema
().
getUnionFields
();
auto
nonUnionFields
=
structValue
.
getSchema
().
getNonUnionFields
();
kj
::
Vector
<
kj
::
StringTree
>
printedFields
(
nonUnionFields
.
size
()
+
(
unionFields
.
size
()
!=
0
));
KJ_IF_MAYBE
(
field
,
structValue
.
which
())
{
if
(
structValue
.
has
(
*
field
))
{
printedFields
.
add
(
kj
::
strTree
(
field
->
getProto
().
getName
(),
" = "
,
print
(
structValue
.
get
(
*
field
),
whichFieldType
(
*
field
),
indent
.
next
(),
PREFIXED
)));
}
}
if
(
mode
==
PARENTHESIZED
)
{
return
indent
.
delimit
(
printedMembers
.
releaseAsArray
(),
mode
);
}
else
{
return
kj
::
strTree
(
'('
,
indent
.
delimit
(
printedMembers
.
releaseAsArray
(),
mode
),
')'
);
for
(
auto
field
:
nonUnionFields
)
{
if
(
structValue
.
has
(
field
))
{
printedFields
.
add
(
kj
::
strTree
(
field
.
getProto
().
getName
(),
" = "
,
print
(
structValue
.
get
(
field
),
whichFieldType
(
field
),
indent
.
next
(),
PREFIXED
)));
}
}
}
case
DynamicValue
:
:
UNION
:
{
auto
unionValue
=
value
.
as
<
DynamicUnion
>
();
KJ_IF_MAYBE
(
tag
,
unionValue
.
which
())
{
return
kj
::
strTree
(
tag
->
getProto
().
getName
(),
'('
,
print
(
unionValue
.
get
(),
whichMemberType
(
*
tag
),
indent
,
PARENTHESIZED
),
')'
);
if
(
mode
==
PARENTHESIZED
)
{
return
indent
.
delimit
(
printedFields
.
releaseAsArray
(),
mode
);
}
else
{
// Unknown union member; must have come from newer
// version of the protocol.
return
kj
::
strTree
(
"<unknown union member>"
);
return
kj
::
strTree
(
'('
,
indent
.
delimit
(
printedFields
.
releaseAsArray
(),
mode
),
')'
);
}
}
case
DynamicValue
:
:
INTERFACE
:
...
...
@@ -240,17 +229,17 @@ static kj::StringTree print(const DynamicValue::Reader& value,
}
kj
::
StringTree
stringify
(
DynamicValue
::
Reader
value
)
{
return
print
(
value
,
schema
::
Type
::
Body
::
STRUCT_TYPE
,
Indent
(
false
),
BARE
);
return
print
(
value
,
schema
2
::
Type
::
STRUCT
,
Indent
(
false
),
BARE
);
}
}
// namespace
kj
::
StringTree
prettyPrint
(
DynamicStruct
::
Reader
value
)
{
return
print
(
value
,
schema
::
Type
::
Body
::
STRUCT_TYPE
,
Indent
(
true
),
BARE
);
return
print
(
value
,
schema
2
::
Type
::
STRUCT
,
Indent
(
true
),
BARE
);
}
kj
::
StringTree
prettyPrint
(
DynamicList
::
Reader
value
)
{
return
print
(
value
,
schema
::
Type
::
Body
::
LIST_TYPE
,
Indent
(
true
),
BARE
);
return
print
(
value
,
schema
2
::
Type
::
LIST
,
Indent
(
true
),
BARE
);
}
kj
::
StringTree
prettyPrint
(
DynamicStruct
::
Builder
value
)
{
return
prettyPrint
(
value
.
asReader
());
}
...
...
@@ -260,8 +249,6 @@ kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value) { return stringif
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
DynamicEnum
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicUnion
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicUnion
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicList
::
Reader
&
value
)
{
return
stringify
(
value
);
}
...
...
@@ -273,11 +260,6 @@ kj::StringTree structString(StructReader reader, const RawSchema& schema) {
return
stringify
(
DynamicStruct
::
Reader
(
StructSchema
(
&
schema
),
reader
));
}
kj
::
StringTree
unionString
(
StructReader
reader
,
const
RawSchema
&
schema
,
uint
memberIndex
)
{
return
stringify
(
DynamicUnion
::
Reader
(
StructSchema
(
&
schema
).
getMembers
()[
memberIndex
].
asUnion
(),
reader
));
}
}
// namespace _ (private)
}
// namespace capnp
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