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

Update capnpc-capnp to use KJ_MAIN.

parent 10697ea1
......@@ -41,6 +41,12 @@
#include <capnp/serialize-packed.h>
#include <limits>
#if HAVE_CONFIG_H
#include "config.h"
#else
#define VERSION "(unknown ekam build)"
#endif
namespace capnp {
namespace compiler {
......@@ -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 {
public:
......
......@@ -29,11 +29,18 @@
#include <kj/debug.h>
#include <kj/io.h>
#include <kj/string-tree.h>
#include <kj/vector.h>
#include "../schema-loader.h"
#include "../dynamic.h"
#include <unistd.h>
#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 {
......@@ -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();
KJ_CONTEXT(proto.getDisplayName());
auto parent = schemaLoader.get(proto.getScopeId());
......@@ -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.");
return "(?)";
}
}
kj::StringTree nodeName(Schema target, Schema scope) {
std::vector<Schema> targetParents;
std::vector<Schema> scopeParts;
kj::StringTree nodeName(Schema target, Schema scope) {
kj::Vector<Schema> targetParents;
kj::Vector<Schema> scopeParts;
{
Schema parent = target;
while (parent.getProto().getScopeId() != 0) {
parent = schemaLoader.get(parent.getProto().getScopeId());
targetParents.push_back(parent);
targetParents.add(parent);
}
}
{
Schema parent = scope;
scopeParts.push_back(parent);
scopeParts.add(parent);
while (parent.getProto().getScopeId() != 0) {
parent = schemaLoader.get(parent.getProto().getScopeId());
scopeParts.push_back(parent);
scopeParts.add(parent);
}
}
// Remove common scope.
while (!scopeParts.empty() && !targetParents.empty() &&
scopeParts.back() == targetParents.back()) {
scopeParts.pop_back();
targetParents.pop_back();
scopeParts.removeLast();
targetParents.removeLast();
}
// TODO(someday): This is broken in that we aren't checking for shadowing.
......@@ -124,13 +147,13 @@ kj::StringTree nodeName(Schema target, Schema scope) {
} else {
path = kj::strTree(kj::mv(path), getUnqualifiedName(part), ".");
}
targetParents.pop_back();
targetParents.removeLast();
}
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();
switch (body.which()) {
case schema::Type::Body::VOID_TYPE: return kj::strTree("Void");
......@@ -158,9 +181,9 @@ kj::StringTree genType(schema::Type::Reader type, Schema scope) {
case schema::Type::Body::OBJECT_TYPE: return kj::strTree("Object");
}
return kj::strTree();
}
}
int typeSizeBits(schema::Type::Reader type) {
int typeSizeBits(schema::Type::Reader type) {
switch (type.getBody().which()) {
case schema::Type::Body::VOID_TYPE: return 0;
case schema::Type::Body::BOOL_TYPE: return 1;
......@@ -183,9 +206,9 @@ int typeSizeBits(schema::Type::Reader type) {
case schema::Type::Body::OBJECT_TYPE: return -1;
}
return 0;
}
}
bool isEmptyValue(schema::Value::Reader value) {
bool isEmptyValue(schema::Value::Reader value) {
auto body = value.getBody();
switch (body.which()) {
case schema::Value::Body::VOID_VALUE: return true;
......@@ -209,9 +232,9 @@ bool isEmptyValue(schema::Value::Reader value) {
case schema::Value::Body::OBJECT_VALUE: 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();
switch (body.which()) {
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,
return kj::strTree(enumerants[body.getEnumValue()].getName());
}
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>(
scope.getDependency(type.getBody().getStructType()).asStruct());
return kj::strTree(value);
......@@ -260,9 +284,9 @@ kj::StringTree genValue(schema::Type::Reader type, schema::Value::Reader value,
}
}
return kj::strTree("");
}
}
kj::StringTree genAnnotation(schema::Annotation::Reader annotation,
kj::StringTree genAnnotation(schema::Annotation::Reader annotation,
Schema scope,
const char* prefix = " ", const char* suffix = "") {
auto decl = schemaLoader.get(annotation.getId());
......@@ -272,17 +296,17 @@ kj::StringTree genAnnotation(schema::Annotation::Reader annotation,
return kj::strTree(prefix, "$", nodeName(decl, scope), "(",
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); });
}
kj::StringTree genAnnotations(Schema schema) {
}
kj::StringTree genAnnotations(Schema schema) {
auto proto = schema.getProto();
return genAnnotations(proto.getAnnotations(), schemaLoader.get(proto.getScopeId()));
}
}
const char* elementSizeName(schema::ElementSize size) {
const char* elementSizeName(schema::ElementSize size) {
switch (size) {
case schema::ElementSize::EMPTY: return "void";
case schema::ElementSize::BIT: return "1-bit";
......@@ -294,9 +318,9 @@ const char* elementSizeName(schema::ElementSize size) {
case schema::ElementSize::INLINE_COMPOSITE: return "inline composite";
}
return "";
}
}
kj::StringTree genStructMember(schema::StructNode::Member::Reader member,
kj::StringTree genStructMember(schema::StructNode::Member::Reader member,
Schema scope, Indent indent, int unionTag = -1) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::FIELD_MEMBER: {
......@@ -340,11 +364,9 @@ kj::StringTree genStructMember(schema::StructNode::Member::Reader member,
}
}
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();
if (proto.getScopeId() != scopeId) {
// 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
case schema::Node::Body::STRUCT_NODE: {
auto body = proto.getBody().getStructNode();
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.getPointerSectionSize(), " ptrs",
body.getPreferredListEncoding() == schema::ElementSize::INLINE_COMPOSITE
......@@ -447,16 +470,16 @@ kj::StringTree genDecl(Schema schema, Text::Reader name, uint64_t scopeId, Inden
}
return kj::strTree();
}
}
kj::StringTree genNestedDecls(Schema schema, Indent indent) {
kj::StringTree genNestedDecls(Schema schema, Indent indent) {
uint64_t id = schema.getProto().getId();
return kj::strTree(KJ_MAP(schema.getProto().getNestedNodes(), nested) {
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 body = proto.getBody();
KJ_REQUIRE(body.which() == schema::Node::Body::FILE_NODE, "Expected a file node.",
......@@ -467,9 +490,9 @@ kj::StringTree genFile(Schema file) {
"@0x", kj::hex(proto.getId()), ";\n",
KJ_MAP(proto.getAnnotations(), ann) { return genAnnotation(ann, file, "", ";\n"); },
genNestedDecls(file, Indent(0)));
}
}
int main(int argc, char* argv[]) {
kj::MainBuilder::Validity run() {
ReaderOptions options;
options.traversalLimitInWords = 1 << 30; // Don't limit.
StreamFdMessageReader reader(STDIN_FILENO, options);
......@@ -489,12 +512,11 @@ int main(int argc, char* argv[]) {
});
}
return 0;
}
return true;
}
};
} // namespace
} // namespace capnp
int main(int argc, char* argv[]) {
return capnp::main(argc, argv);
}
KJ_MAIN(capnp::CapnpcCapnpMain);
......@@ -350,6 +350,11 @@ public:
template <typename Iterator>
void addAll(Iterator start, Iterator end);
void removeLast() {
KJ_IREQUIRE(pos > ptr, "No elements present to remove.");
kj::dtor(*--pos);
}
Array<T> finish() {
// 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
......
......@@ -87,6 +87,10 @@ public:
addAll(container.begin(), container.end());
}
inline void removeLast() {
builder.removeLast();
}
private:
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