Commit 3b0e4f1e authored by Kenton Varda's avatar Kenton Varda

Update capnpc-capnp to use KJ_MAIN.

parent 10697ea1
...@@ -41,6 +41,12 @@ ...@@ -41,6 +41,12 @@
#include <capnp/serialize-packed.h> #include <capnp/serialize-packed.h>
#include <limits> #include <limits>
#if HAVE_CONFIG_H
#include "config.h"
#else
#define VERSION "(unknown ekam build)"
#endif
namespace capnp { namespace capnp {
namespace compiler { namespace compiler {
...@@ -65,7 +71,7 @@ public: ...@@ -65,7 +71,7 @@ public:
} }
}; };
static const char VERSION_STRING[] = "Cap'n Proto version 0.2"; static const char VERSION_STRING[] = "Cap'n Proto version " VERSION;
class CompilerMain final: public GlobalErrorReporter { class CompilerMain final: public GlobalErrorReporter {
public: public:
......
...@@ -29,11 +29,18 @@ ...@@ -29,11 +29,18 @@
#include <kj/debug.h> #include <kj/debug.h>
#include <kj/io.h> #include <kj/io.h>
#include <kj/string-tree.h> #include <kj/string-tree.h>
#include <kj/vector.h>
#include "../schema-loader.h" #include "../schema-loader.h"
#include "../dynamic.h" #include "../dynamic.h"
#include <unistd.h> #include <unistd.h>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <kj/main.h>
#if HAVE_CONFIG_H
#include "config.h"
#else
#define VERSION "(unknown ekam build)"
#endif
namespace capnp { namespace capnp {
namespace { namespace {
...@@ -70,9 +77,25 @@ inline Indent KJ_STRINGIFY(const Indent& indent) { ...@@ -70,9 +77,25 @@ inline Indent KJ_STRINGIFY(const Indent& indent) {
// ======================================================================================= // =======================================================================================
SchemaLoader schemaLoader; class CapnpcCapnpMain {
public:
CapnpcCapnpMain(kj::ProcessContext& context): context(context) {}
kj::MainFunc getMain() {
return kj::MainBuilder(context, "Cap'n Proto loopback plugin version " VERSION,
"This is a Cap'n Proto compiler plugin which \"de-compiles\" the schema back into "
"Cap'n Proto schema language format, with comments showing the offsets chosen by the "
"compiler. This is meant to be run using the Cap'n Proto compiler, e.g.:\n"
" capnp compile -ocapnp foo.capnp")
.callAfterParsing(KJ_BIND_METHOD(*this, run))
.build();
}
Text::Reader getUnqualifiedName(Schema schema) { private:
kj::ProcessContext& context;
SchemaLoader schemaLoader;
Text::Reader getUnqualifiedName(Schema schema) {
auto proto = schema.getProto(); auto proto = schema.getProto();
KJ_CONTEXT(proto.getDisplayName()); KJ_CONTEXT(proto.getDisplayName());
auto parent = schemaLoader.get(proto.getScopeId()); auto parent = schemaLoader.get(proto.getScopeId());
...@@ -83,34 +106,34 @@ Text::Reader getUnqualifiedName(Schema schema) { ...@@ -83,34 +106,34 @@ Text::Reader getUnqualifiedName(Schema schema) {
} }
KJ_FAIL_REQUIRE("A schema Node's supposed scope did not contain the node as a NestedNode."); KJ_FAIL_REQUIRE("A schema Node's supposed scope did not contain the node as a NestedNode.");
return "(?)"; return "(?)";
} }
kj::StringTree nodeName(Schema target, Schema scope) { kj::StringTree nodeName(Schema target, Schema scope) {
std::vector<Schema> targetParents; kj::Vector<Schema> targetParents;
std::vector<Schema> scopeParts; kj::Vector<Schema> scopeParts;
{ {
Schema parent = target; Schema parent = target;
while (parent.getProto().getScopeId() != 0) { while (parent.getProto().getScopeId() != 0) {
parent = schemaLoader.get(parent.getProto().getScopeId()); parent = schemaLoader.get(parent.getProto().getScopeId());
targetParents.push_back(parent); targetParents.add(parent);
} }
} }
{ {
Schema parent = scope; Schema parent = scope;
scopeParts.push_back(parent); scopeParts.add(parent);
while (parent.getProto().getScopeId() != 0) { while (parent.getProto().getScopeId() != 0) {
parent = schemaLoader.get(parent.getProto().getScopeId()); parent = schemaLoader.get(parent.getProto().getScopeId());
scopeParts.push_back(parent); scopeParts.add(parent);
} }
} }
// Remove common scope. // Remove common scope.
while (!scopeParts.empty() && !targetParents.empty() && while (!scopeParts.empty() && !targetParents.empty() &&
scopeParts.back() == targetParents.back()) { scopeParts.back() == targetParents.back()) {
scopeParts.pop_back(); scopeParts.removeLast();
targetParents.pop_back(); targetParents.removeLast();
} }
// TODO(someday): This is broken in that we aren't checking for shadowing. // TODO(someday): This is broken in that we aren't checking for shadowing.
...@@ -124,13 +147,13 @@ kj::StringTree nodeName(Schema target, Schema scope) { ...@@ -124,13 +147,13 @@ kj::StringTree nodeName(Schema target, Schema scope) {
} else { } else {
path = kj::strTree(kj::mv(path), getUnqualifiedName(part), "."); path = kj::strTree(kj::mv(path), getUnqualifiedName(part), ".");
} }
targetParents.pop_back(); targetParents.removeLast();
} }
return kj::strTree(kj::mv(path), getUnqualifiedName(target)); return kj::strTree(kj::mv(path), getUnqualifiedName(target));
} }
kj::StringTree genType(schema::Type::Reader type, Schema scope) { kj::StringTree genType(schema::Type::Reader type, Schema scope) {
auto body = type.getBody(); auto body = type.getBody();
switch (body.which()) { switch (body.which()) {
case schema::Type::Body::VOID_TYPE: return kj::strTree("Void"); case schema::Type::Body::VOID_TYPE: return kj::strTree("Void");
...@@ -158,9 +181,9 @@ kj::StringTree genType(schema::Type::Reader type, Schema scope) { ...@@ -158,9 +181,9 @@ kj::StringTree genType(schema::Type::Reader type, Schema scope) {
case schema::Type::Body::OBJECT_TYPE: return kj::strTree("Object"); case schema::Type::Body::OBJECT_TYPE: return kj::strTree("Object");
} }
return kj::strTree(); return kj::strTree();
} }
int typeSizeBits(schema::Type::Reader type) { int typeSizeBits(schema::Type::Reader type) {
switch (type.getBody().which()) { switch (type.getBody().which()) {
case schema::Type::Body::VOID_TYPE: return 0; case schema::Type::Body::VOID_TYPE: return 0;
case schema::Type::Body::BOOL_TYPE: return 1; case schema::Type::Body::BOOL_TYPE: return 1;
...@@ -183,9 +206,9 @@ int typeSizeBits(schema::Type::Reader type) { ...@@ -183,9 +206,9 @@ int typeSizeBits(schema::Type::Reader type) {
case schema::Type::Body::OBJECT_TYPE: return -1; case schema::Type::Body::OBJECT_TYPE: return -1;
} }
return 0; return 0;
} }
bool isEmptyValue(schema::Value::Reader value) { bool isEmptyValue(schema::Value::Reader value) {
auto body = value.getBody(); auto body = value.getBody();
switch (body.which()) { switch (body.which()) {
case schema::Value::Body::VOID_VALUE: return true; case schema::Value::Body::VOID_VALUE: return true;
...@@ -209,9 +232,9 @@ bool isEmptyValue(schema::Value::Reader value) { ...@@ -209,9 +232,9 @@ bool isEmptyValue(schema::Value::Reader value) {
case schema::Value::Body::OBJECT_VALUE: return true; case schema::Value::Body::OBJECT_VALUE: return true;
} }
return true; return true;
} }
kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value, Schema scope) { kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value, Schema scope) {
auto body = value.getBody(); auto body = value.getBody();
switch (body.which()) { switch (body.which()) {
case schema::Value::Body::VOID_VALUE: return kj::strTree("void"); case schema::Value::Body::VOID_VALUE: return kj::strTree("void");
...@@ -247,7 +270,8 @@ kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value, ...@@ -247,7 +270,8 @@ kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value,
return kj::strTree(enumerants[body.getEnumValue()].getName()); return kj::strTree(enumerants[body.getEnumValue()].getName());
} }
case schema::Value::Body::STRUCT_VALUE: { case schema::Value::Body::STRUCT_VALUE: {
KJ_REQUIRE(type.getBody().which() == schema::Type::Body::STRUCT_TYPE, "type/value mismatch"); KJ_REQUIRE(type.getBody().which() == schema::Type::Body::STRUCT_TYPE,
"type/value mismatch");
auto value = body.getStructValue<DynamicStruct>( auto value = body.getStructValue<DynamicStruct>(
scope.getDependency(type.getBody().getStructType()).asStruct()); scope.getDependency(type.getBody().getStructType()).asStruct());
return kj::strTree(value); return kj::strTree(value);
...@@ -260,9 +284,9 @@ kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value, ...@@ -260,9 +284,9 @@ kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value,
} }
} }
return kj::strTree(""); return kj::strTree("");
} }
kj::StringTree genAnnotation(schema::Annotation::Reader annotation, kj::StringTree genAnnotation(schema::Annotation::Reader annotation,
Schema scope, Schema scope,
const char* prefix = " ", const char* suffix = "") { const char* prefix = " ", const char* suffix = "") {
auto decl = schemaLoader.get(annotation.getId()); auto decl = schemaLoader.get(annotation.getId());
...@@ -272,17 +296,17 @@ kj::StringTree genAnnotation(schema::Annotation::Reader annotation, ...@@ -272,17 +296,17 @@ kj::StringTree genAnnotation(schema::Annotation::Reader annotation,
return kj::strTree(prefix, "$", nodeName(decl, scope), "(", return kj::strTree(prefix, "$", nodeName(decl, scope), "(",
genValue(annDecl.getType(), annotation.getValue(), scope), ")", suffix); genValue(annDecl.getType(), annotation.getValue(), scope), ")", suffix);
} }
kj::StringTree genAnnotations(List<schema::Annotation>::Reader list, Schema scope) { kj::StringTree genAnnotations(List<schema::Annotation>::Reader list, Schema scope) {
return kj::strTree(KJ_MAP(list, ann) { return genAnnotation(ann, scope); }); return kj::strTree(KJ_MAP(list, ann) { return genAnnotation(ann, scope); });
} }
kj::StringTree genAnnotations(Schema schema) { kj::StringTree genAnnotations(Schema schema) {
auto proto = schema.getProto(); auto proto = schema.getProto();
return genAnnotations(proto.getAnnotations(), schemaLoader.get(proto.getScopeId())); return genAnnotations(proto.getAnnotations(), schemaLoader.get(proto.getScopeId()));
} }
const char* elementSizeName(schema::ElementSize size) { const char* elementSizeName(schema::ElementSize size) {
switch (size) { switch (size) {
case schema::ElementSize::EMPTY: return "void"; case schema::ElementSize::EMPTY: return "void";
case schema::ElementSize::BIT: return "1-bit"; case schema::ElementSize::BIT: return "1-bit";
...@@ -294,9 +318,9 @@ const char* elementSizeName(schema::ElementSize size) { ...@@ -294,9 +318,9 @@ const char* elementSizeName(schema::ElementSize size) {
case schema::ElementSize::INLINE_COMPOSITE: return "inline composite"; case schema::ElementSize::INLINE_COMPOSITE: return "inline composite";
} }
return ""; return "";
} }
kj::StringTree genStructMember(schema::StructNode::Member::Reader member, kj::StringTree genStructMember(schema::StructNode::Member::Reader member,
Schema scope, Indent indent, int unionTag = -1) { Schema scope, Indent indent, int unionTag = -1) {
switch (member.getBody().which()) { switch (member.getBody().which()) {
case schema::StructNode::Member::Body::FIELD_MEMBER: { case schema::StructNode::Member::Body::FIELD_MEMBER: {
...@@ -340,11 +364,9 @@ kj::StringTree genStructMember(schema::StructNode::Member::Reader member, ...@@ -340,11 +364,9 @@ kj::StringTree genStructMember(schema::StructNode::Member::Reader member,
} }
} }
return kj::strTree(); return kj::strTree();
} }
kj::StringTree genNestedDecls(Schema schema, Indent indent);
kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Indent indent) { kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Indent indent) {
auto proto = schema.getProto(); auto proto = schema.getProto();
if (proto.getScopeId() != scopeId) { if (proto.getScopeId() != scopeId) {
// This appears to be an alias for something declared elsewhere. // This appears to be an alias for something declared elsewhere.
...@@ -358,7 +380,8 @@ kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Inden ...@@ -358,7 +380,8 @@ kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Inden
case schema::Node::Body::STRUCT_NODE: { case schema::Node::Body::STRUCT_NODE: {
auto body = proto.getBody().getStructNode(); auto body = proto.getBody().getStructNode();
return kj::strTree( return kj::strTree(
indent, "struct ", name, " @0x", kj::hex(proto.getId()), genAnnotations(schema), " { # ", indent, "struct ", name,
" @0x", kj::hex(proto.getId()), genAnnotations(schema), " { # ",
body.getDataSectionWordSize() * 8, " bytes, ", body.getDataSectionWordSize() * 8, " bytes, ",
body.getPointerSectionSize(), " ptrs", body.getPointerSectionSize(), " ptrs",
body.getPreferredListEncoding() == schema::ElementSize::INLINE_COMPOSITE body.getPreferredListEncoding() == schema::ElementSize::INLINE_COMPOSITE
...@@ -447,16 +470,16 @@ kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Inden ...@@ -447,16 +470,16 @@ kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Inden
} }
return kj::strTree(); return kj::strTree();
} }
kj::StringTree genNestedDecls(Schema schema, Indent indent) { kj::StringTree genNestedDecls(Schema schema, Indent indent) {
uint64_t id = schema.getProto().getId(); uint64_t id = schema.getProto().getId();
return kj::strTree(KJ_MAP(schema.getProto().getNestedNodes(), nested) { return kj::strTree(KJ_MAP(schema.getProto().getNestedNodes(), nested) {
return genDecl(schemaLoader.get(nested.getId()), nested.getName(), id, indent); return genDecl(schemaLoader.get(nested.getId()), nested.getName(), id, indent);
}); });
} }
kj::StringTree genFile(Schema file) { kj::StringTree genFile(Schema file) {
auto proto = file.getProto(); auto proto = file.getProto();
auto body = proto.getBody(); auto body = proto.getBody();
KJ_REQUIRE(body.which() == schema::Node::Body::FILE_NODE, "Expected a file node.", KJ_REQUIRE(body.which() == schema::Node::Body::FILE_NODE, "Expected a file node.",
...@@ -467,9 +490,9 @@ kj::StringTree genFile(Schema file) { ...@@ -467,9 +490,9 @@ kj::StringTree genFile(Schema file) {
"@0x", kj::hex(proto.getId()), ";\n", "@0x", kj::hex(proto.getId()), ";\n",
KJ_MAP(proto.getAnnotations(), ann) { return genAnnotation(ann, file, "", ";\n"); }, KJ_MAP(proto.getAnnotations(), ann) { return genAnnotation(ann, file, "", ";\n"); },
genNestedDecls(file, Indent(0))); genNestedDecls(file, Indent(0)));
} }
int main(int argc, char* argv[]) { kj::MainBuilder::Validity run() {
ReaderOptions options; ReaderOptions options;
options.traversalLimitInWords = 1 << 30; // Don't limit. options.traversalLimitInWords = 1 << 30; // Don't limit.
StreamFdMessageReader reader(STDIN_FILENO, options); StreamFdMessageReader reader(STDIN_FILENO, options);
...@@ -489,12 +512,11 @@ int main(int argc, char* argv[]) { ...@@ -489,12 +512,11 @@ int main(int argc, char* argv[]) {
}); });
} }
return 0; return true;
} }
};
} // namespace } // namespace
} // namespace capnp } // namespace capnp
int main(int argc, char* argv[]) { KJ_MAIN(capnp::CapnpcCapnpMain);
return capnp::main(argc, argv);
}
...@@ -350,6 +350,11 @@ public: ...@@ -350,6 +350,11 @@ public:
template <typename Iterator> template <typename Iterator>
void addAll(Iterator start, Iterator end); void addAll(Iterator start, Iterator end);
void removeLast() {
KJ_IREQUIRE(pos > ptr, "No elements present to remove.");
kj::dtor(*--pos);
}
Array<T> finish() { Array<T> finish() {
// We could safely remove this check if we assume that the disposer implementation doesn't // We could safely remove this check if we assume that the disposer implementation doesn't
// need to know the original capacity, as is thes case with HeapArrayDisposer since it uses // need to know the original capacity, as is thes case with HeapArrayDisposer since it uses
......
...@@ -87,6 +87,10 @@ public: ...@@ -87,6 +87,10 @@ public:
addAll(container.begin(), container.end()); addAll(container.begin(), container.end());
} }
inline void removeLast() {
builder.removeLast();
}
private: private:
ArrayBuilder<T> builder; ArrayBuilder<T> builder;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment