capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

parser.c++ (50098B)


      1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 #if _WIN32
     23 #include <kj/win32-api-version.h>
     24 #endif
     25 
     26 #include "parser.h"
     27 #include "type-id.h"
     28 #include <capnp/dynamic.h>
     29 #include <kj/debug.h>
     30 #include <kj/encoding.h>
     31 #if !_MSC_VER
     32 #include <unistd.h>
     33 #endif
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #include <fcntl.h>
     37 
     38 #if _WIN32
     39 #include <windows.h>
     40 #include <wincrypt.h>
     41 #undef CONST
     42 #include <kj/windows-sanity.h>
     43 #endif
     44 
     45 namespace capnp {
     46 namespace compiler {
     47 
     48 uint64_t generateRandomId() {
     49   uint64_t result;
     50 
     51 #if _WIN32
     52   HCRYPTPROV handle;
     53   KJ_ASSERT(CryptAcquireContextW(&handle, nullptr, nullptr,
     54                                  PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT));
     55   KJ_DEFER(KJ_ASSERT(CryptReleaseContext(handle, 0)) {break;});
     56 
     57   KJ_ASSERT(CryptGenRandom(handle, sizeof(result), reinterpret_cast<BYTE*>(&result)));
     58 
     59 #else
     60   int fd;
     61   KJ_SYSCALL(fd = open("/dev/urandom", O_RDONLY));
     62 
     63   ssize_t n;
     64   KJ_SYSCALL(n = read(fd, &result, sizeof(result)), "/dev/urandom");
     65   KJ_ASSERT(n == sizeof(result), "Incomplete read from /dev/urandom.", n);
     66 #endif
     67 
     68   return result | (1ull << 63);
     69 }
     70 
     71 void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
     72                ErrorReporter& errorReporter) {
     73   CapnpParser parser(Orphanage::getForMessageContaining(result), errorReporter);
     74 
     75   kj::Vector<Orphan<Declaration>> decls(statements.size());
     76   kj::Vector<Orphan<Declaration::AnnotationApplication>> annotations;
     77 
     78   auto fileDecl = result.getRoot();
     79   fileDecl.setFile(VOID);
     80 
     81   for (auto statement: statements) {
     82     KJ_IF_MAYBE(decl, parser.parseStatement(statement, parser.getParsers().fileLevelDecl)) {
     83       Declaration::Builder builder = decl->get();
     84       switch (builder.which()) {
     85         case Declaration::NAKED_ID:
     86           if (fileDecl.getId().isUid()) {
     87             errorReporter.addError(builder.getStartByte(), builder.getEndByte(),
     88                                    "File can only have one ID.");
     89           } else {
     90             fileDecl.getId().adoptUid(builder.disownNakedId());
     91             if (builder.hasDocComment()) {
     92               fileDecl.adoptDocComment(builder.disownDocComment());
     93             }
     94           }
     95           break;
     96         case Declaration::NAKED_ANNOTATION:
     97           annotations.add(builder.disownNakedAnnotation());
     98           break;
     99         default:
    100           decls.add(kj::mv(*decl));
    101           break;
    102       }
    103     }
    104   }
    105 
    106   if (fileDecl.getId().which() != Declaration::Id::UID) {
    107     // We didn't see an ID. Generate one randomly for now.
    108     uint64_t id = generateRandomId();
    109     fileDecl.getId().initUid().setValue(id);
    110 
    111     // Don't report missing ID if there was a parse error, because quite often the parse error
    112     // prevents us from parsing the ID even though it is actually there.
    113     if (!errorReporter.hadErrors()) {
    114       errorReporter.addError(0, 0,
    115           kj::str("File does not declare an ID.  I've generated one for you.  Add this line to "
    116                   "your file: @0x", kj::hex(id), ";"));
    117     }
    118   }
    119 
    120   auto declsBuilder = fileDecl.initNestedDecls(decls.size());
    121   for (size_t i = 0; i < decls.size(); i++) {
    122     declsBuilder.adoptWithCaveats(i, kj::mv(decls[i]));
    123   }
    124 
    125   auto annotationsBuilder = fileDecl.initAnnotations(annotations.size());
    126   for (size_t i = 0; i < annotations.size(); i++) {
    127     annotationsBuilder.adoptWithCaveats(i, kj::mv(annotations[i]));
    128   }
    129 }
    130 
    131 namespace p = kj::parse;
    132 
    133 namespace {
    134 
    135 // =======================================================================================
    136 
    137 template <typename T>
    138 struct Located {
    139   T value;
    140   uint32_t startByte;
    141   uint32_t endByte;
    142 
    143   template <typename Builder>
    144   void copyLocationTo(Builder builder) {
    145     builder.setStartByte(startByte);
    146     builder.setEndByte(endByte);
    147   }
    148   template <typename Builder>
    149   void copyTo(Builder builder) {
    150     builder.setValue(value);
    151     copyLocationTo(builder);
    152   }
    153   template <typename Result>
    154   Orphan<Result> asProto(Orphanage orphanage) {
    155     auto result = orphanage.newOrphan<Result>();
    156     copyTo(result.get());
    157     return result;
    158   }
    159   template <typename Other>
    160   Located<kj::Decay<Other>> rewrap(Other&& other) {
    161     return Located<Other>(kj::fwd<Other>(other), startByte, endByte);
    162   }
    163 
    164   Located(const T& value, uint32_t startByte, uint32_t endByte)
    165       : value(value), startByte(startByte), endByte(endByte) {}
    166   Located(T&& value, uint32_t startByte, uint32_t endByte)
    167       : value(kj::mv(value)), startByte(startByte), endByte(endByte) {}
    168 };
    169 
    170 // =======================================================================================
    171 
    172 template <typename T, Token::Which type, T (Token::Reader::*get)() const>
    173 struct MatchTokenType {
    174   kj::Maybe<Located<T>> operator()(Token::Reader token) const {
    175     if (token.which() == type) {
    176       return Located<T>((token.*get)(), token.getStartByte(), token.getEndByte());
    177     } else {
    178       return nullptr;
    179     }
    180   }
    181 };
    182 
    183 #define TOKEN_TYPE_PARSER(type, discrim, getter) \
    184     p::transformOrReject(p::any, \
    185         MatchTokenType<type, Token::discrim, &Token::Reader::getter>())
    186 
    187 constexpr auto identifier = TOKEN_TYPE_PARSER(Text::Reader, IDENTIFIER, getIdentifier);
    188 constexpr auto stringLiteral = TOKEN_TYPE_PARSER(Text::Reader, STRING_LITERAL, getStringLiteral);
    189 constexpr auto binaryLiteral = TOKEN_TYPE_PARSER(Data::Reader, BINARY_LITERAL, getBinaryLiteral);
    190 constexpr auto integerLiteral = TOKEN_TYPE_PARSER(uint64_t, INTEGER_LITERAL, getIntegerLiteral);
    191 constexpr auto floatLiteral = TOKEN_TYPE_PARSER(double, FLOAT_LITERAL, getFloatLiteral);
    192 constexpr auto operatorToken = TOKEN_TYPE_PARSER(Text::Reader, OPERATOR, getOperator);
    193 constexpr auto rawParenthesizedList =
    194     TOKEN_TYPE_PARSER(List<List<Token>>::Reader, PARENTHESIZED_LIST, getParenthesizedList);
    195 constexpr auto rawBracketedList =
    196     TOKEN_TYPE_PARSER(List<List<Token>>::Reader, BRACKETED_LIST, getBracketedList);
    197 
    198 // =======================================================================================
    199 
    200 class ExactString {
    201 public:
    202   constexpr ExactString(const char* expected): expected(expected) {}
    203 
    204   kj::Maybe<kj::Tuple<>> operator()(Located<Text::Reader>&& text) const {
    205     if (text.value == expected) {
    206       return kj::Tuple<>();
    207     } else {
    208       return nullptr;
    209     }
    210   }
    211 
    212 private:
    213   const char* expected;
    214 };
    215 
    216 constexpr auto keyword(const char* expected)
    217     -> decltype(p::transformOrReject(identifier, ExactString(expected))) {
    218   return p::transformOrReject(identifier, ExactString(expected));
    219 }
    220 
    221 constexpr auto op(const char* expected)
    222     -> decltype(p::transformOrReject(operatorToken, ExactString(expected))) {
    223   return p::transformOrReject(operatorToken, ExactString(expected));
    224 }
    225 
    226 class LocatedExactString {
    227 public:
    228   constexpr LocatedExactString(const char* expected): expected(expected) {}
    229 
    230   kj::Maybe<Located<Text::Reader>> operator()(Located<Text::Reader>&& text) const {
    231     if (text.value == expected) {
    232       return kj::mv(text);
    233     } else {
    234       return nullptr;
    235     }
    236   }
    237 
    238 private:
    239   const char* expected;
    240 };
    241 
    242 constexpr auto locatedKeyword(const char* expected)
    243     -> decltype(p::transformOrReject(identifier, LocatedExactString(expected))) {
    244   return p::transformOrReject(identifier, LocatedExactString(expected));
    245 }
    246 
    247 // =======================================================================================
    248 
    249 template <typename ItemParser>
    250 class ParseListItems {
    251   // Transformer that parses all items in the input token sequence list using the given parser.
    252 
    253 public:
    254   constexpr ParseListItems(ItemParser&& itemParser, ErrorReporter& errorReporter)
    255       : itemParser(p::sequence(kj::fwd<ItemParser>(itemParser), p::endOfInput)),
    256         errorReporter(errorReporter) {}
    257 
    258   Located<kj::Array<kj::Maybe<p::OutputType<ItemParser, CapnpParser::ParserInput>>>> operator()(
    259       Located<List<List<Token>>::Reader>&& items) const {
    260     auto result = kj::heapArray<kj::Maybe<p::OutputType<ItemParser, CapnpParser::ParserInput>>>(
    261         items.value.size());
    262     for (uint i = 0; i < items.value.size(); i++) {
    263       auto item = items.value[i];
    264       CapnpParser::ParserInput input(item.begin(), item.end());
    265       result[i] = itemParser(input);
    266       if (result[i] == nullptr) {
    267         // Parsing failed.  Report an error.
    268         auto best = input.getBest();
    269         if (best < item.end()) {
    270           // Report error from the point where parsing failed to the end of the item.
    271           errorReporter.addError(
    272               best->getStartByte(), (item.end() - 1)->getEndByte(), "Parse error.");
    273         } else if (item.size() > 0) {
    274           // The item is non-empty and the parser consumed all of it before failing.  Report an
    275           // error for the whole thing.
    276           errorReporter.addError(
    277               item.begin()->getStartByte(), (item.end() - 1)->getEndByte(), "Parse error.");
    278         } else {
    279           // The item has no content.
    280           // TODO(cleanup):  We don't actually know the item's location, so we can only report
    281           //   an error across the whole list.  Fix this.
    282           errorReporter.addError(items.startByte, items.endByte, "Parse error: Empty list item.");
    283         }
    284       }
    285     }
    286     return Located<kj::Array<kj::Maybe<p::OutputType<ItemParser, CapnpParser::ParserInput>>>>(
    287         kj::mv(result), items.startByte, items.endByte);
    288   }
    289 
    290 private:
    291   decltype(p::sequence(kj::instance<ItemParser>(), p::endOfInput)) itemParser;
    292   ErrorReporter& errorReporter;
    293 };
    294 
    295 template <typename ItemParser>
    296 constexpr auto parenthesizedList(ItemParser&& itemParser, ErrorReporter& errorReporter) -> decltype(
    297          transform(rawParenthesizedList, ParseListItems<ItemParser>(
    298              kj::fwd<ItemParser>(itemParser), errorReporter))) {
    299   return transform(rawParenthesizedList, ParseListItems<ItemParser>(
    300              kj::fwd<ItemParser>(itemParser), errorReporter));
    301 }
    302 
    303 template <typename ItemParser>
    304 constexpr auto bracketedList(ItemParser&& itemParser, ErrorReporter& errorReporter) -> decltype(
    305          transform(rawBracketedList, ParseListItems<ItemParser>(
    306              kj::fwd<ItemParser>(itemParser), errorReporter))) {
    307   return transform(rawBracketedList, ParseListItems<ItemParser>(
    308              kj::fwd<ItemParser>(itemParser), errorReporter));
    309 }
    310 
    311 // =======================================================================================
    312 
    313 template <typename T>
    314 Orphan<List<T>> arrayToList(Orphanage& orphanage, kj::Array<Orphan<T>>&& elements) {
    315   auto result = orphanage.newOrphan<List<T>>(elements.size());
    316   auto builder = result.get();
    317   for (size_t i = 0; i < elements.size(); i++) {
    318     builder.adoptWithCaveats(i, kj::mv(elements[i]));
    319   }
    320   return kj::mv(result);
    321 }
    322 
    323 static void initGenericParams(Declaration::Builder builder,
    324     kj::Maybe<Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>>&& genericParameters) {
    325   KJ_IF_MAYBE(p, genericParameters) {
    326     auto params = builder.initParameters(p->value.size());
    327     for (uint i: kj::indices(p->value)) {
    328       KJ_IF_MAYBE(name, p->value[i]) {
    329         auto param = params[i];
    330         param.setName(name->value);
    331         name->copyLocationTo(param);
    332       }
    333     }
    334   }
    335 }
    336 
    337 static Declaration::Builder initDecl(
    338     Declaration::Builder builder, Located<Text::Reader>&& name,
    339     kj::Maybe<Orphan<LocatedInteger>>&& id,
    340     kj::Maybe<Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>>&& genericParameters,
    341     kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations) {
    342   name.copyTo(builder.initName());
    343   KJ_IF_MAYBE(i, id) {
    344     builder.getId().adoptUid(kj::mv(*i));
    345   }
    346 
    347   initGenericParams(builder, kj::mv(genericParameters));
    348 
    349   auto list = builder.initAnnotations(annotations.size());
    350   for (uint i = 0; i < annotations.size(); i++) {
    351     list.adoptWithCaveats(i, kj::mv(annotations[i]));
    352   }
    353   return builder;
    354 }
    355 
    356 static Declaration::Builder initMemberDecl(
    357     Declaration::Builder builder, Located<Text::Reader>&& name,
    358     Orphan<LocatedInteger>&& ordinal,
    359     kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations) {
    360   name.copyTo(builder.initName());
    361   builder.getId().adoptOrdinal(kj::mv(ordinal));
    362   auto list = builder.initAnnotations(annotations.size());
    363   for (uint i = 0; i < annotations.size(); i++) {
    364     list.adoptWithCaveats(i, kj::mv(annotations[i]));
    365   }
    366   return builder;
    367 }
    368 
    369 template <typename BuilderType>
    370 void initLocation(kj::parse::Span<typename List<Token>::Reader::Iterator> location,
    371                   BuilderType builder) {
    372   if (location.begin() < location.end()) {
    373     builder.setStartByte(location.begin()->getStartByte());
    374     builder.setEndByte((location.end() - 1)->getEndByte());
    375   }
    376 }
    377 
    378 }  // namespace
    379 
    380 // =======================================================================================
    381 
    382 CapnpParser::CapnpParser(Orphanage orphanageParam, ErrorReporter& errorReporterParam)
    383     : orphanage(orphanageParam), errorReporter(errorReporterParam) {
    384   auto& tupleElement = arena.copy(p::transform(
    385       p::sequence(p::optional(p::sequence(identifier, op("="))), parsers.expression),
    386       [this](kj::Maybe<Located<Text::Reader>>&& fieldName, Orphan<Expression>&& fieldValue)
    387              -> Orphan<Expression::Param> {
    388         auto result = orphanage.newOrphan<Expression::Param>();
    389         auto builder = result.get();
    390         KJ_IF_MAYBE(fn, fieldName) {
    391           fn->copyTo(builder.initNamed());
    392         } else {
    393           builder.setUnnamed();
    394         }
    395         builder.adoptValue(kj::mv(fieldValue));
    396         return kj::mv(result);
    397       }));
    398 
    399   auto& tuple = arena.copy<Parser<Located<Orphan<List<Expression::Param>>>>>(
    400       arena.copy(p::transform(
    401         parenthesizedList(tupleElement, errorReporter),
    402         [this](Located<kj::Array<kj::Maybe<Orphan<Expression::Param>>>>&& elements)
    403                -> Located<Orphan<List<Expression::Param>>> {
    404           auto result = orphanage.newOrphan<List<Expression::Param>>(elements.value.size());
    405           auto builder = result.get();
    406           for (uint i: kj::indices(elements.value)) {
    407             KJ_IF_MAYBE(e, elements.value[i]) {
    408               builder.adoptWithCaveats(i, kj::mv(*e));
    409             } else {
    410               builder[i].initValue().setUnknown();
    411             }
    412           }
    413           return elements.rewrap(kj::mv(result));
    414         })));
    415 
    416   parsers.expression = arena.copy(p::transform(
    417       p::sequence(
    418           // Base expression.
    419           p::oneOf(
    420               p::transform(integerLiteral,
    421                   [this](Located<uint64_t>&& value) -> Orphan<Expression> {
    422                     auto result = orphanage.newOrphan<Expression>();
    423                     auto builder = result.get();
    424                     builder.setPositiveInt(value.value);
    425                     value.copyLocationTo(builder);
    426                     return result;
    427                   }),
    428               p::transform(p::sequence(op("-"), integerLiteral),
    429                   [this](Located<uint64_t>&& value) -> Orphan<Expression> {
    430                     auto result = orphanage.newOrphan<Expression>();
    431                     auto builder = result.get();
    432                     builder.setNegativeInt(value.value);
    433                     value.copyLocationTo(builder);
    434                     return result;
    435                   }),
    436               p::transform(floatLiteral,
    437                   [this](Located<double>&& value) -> Orphan<Expression> {
    438                     auto result = orphanage.newOrphan<Expression>();
    439                     auto builder = result.get();
    440                     builder.setFloat(value.value);
    441                     value.copyLocationTo(builder);
    442                     return result;
    443                   }),
    444               p::transform(p::sequence(op("-"), floatLiteral),
    445                   [this](Located<double>&& value) -> Orphan<Expression> {
    446                     auto result = orphanage.newOrphan<Expression>();
    447                     auto builder = result.get();
    448                     builder.setFloat(-value.value);
    449                     value.copyLocationTo(builder);
    450                     return result;
    451                   }),
    452               p::transformWithLocation(p::sequence(op("-"), keyword("inf")),
    453                   [this](kj::parse::Span<List<Token>::Reader::Iterator> location)
    454                       -> Orphan<Expression> {
    455                     auto result = orphanage.newOrphan<Expression>();
    456                     auto builder = result.get();
    457                     builder.setFloat(-kj::inf());
    458                     initLocation(location, builder);
    459                     return result;
    460                   }),
    461               p::transform(p::oneOrMore(stringLiteral),
    462                   [this](kj::Array<Located<Text::Reader>>&& value) -> Orphan<Expression> {
    463                     auto result = orphanage.newOrphan<Expression>();
    464                     auto builder = result.get();
    465                     builder.setString(kj::strArray(
    466                         KJ_MAP(part, value) { return part.value; }, ""));
    467                     builder.setStartByte(value.front().startByte);
    468                     builder.setEndByte(value.back().endByte);
    469                     return result;
    470                   }),
    471               p::transform(binaryLiteral,
    472                   [this](Located<Data::Reader>&& value) -> Orphan<Expression> {
    473                     auto result = orphanage.newOrphan<Expression>();
    474                     auto builder = result.get();
    475                     builder.setBinary(value.value);
    476                     value.copyLocationTo(builder);
    477                     return result;
    478                   }),
    479               p::transform(bracketedList(parsers.expression, errorReporter),
    480                   [this](Located<kj::Array<kj::Maybe<Orphan<Expression>>>>&& value)
    481                       -> Orphan<Expression> {
    482                     auto result = orphanage.newOrphan<Expression>();
    483                     auto builder = result.get();
    484                     auto listBuilder = builder.initList(value.value.size());
    485                     for (uint i = 0; i < value.value.size(); i++) {
    486                       KJ_IF_MAYBE(element, value.value[i]) {
    487                         listBuilder.adoptWithCaveats(i, kj::mv(*element));
    488                       }
    489                     }
    490                     value.copyLocationTo(builder);
    491                     return result;
    492                   }),
    493               p::transform(tuple,
    494                   [this](Located<Orphan<List<Expression::Param>>>&& value)
    495                       -> Orphan<Expression> {
    496                     auto elements = value.value.get();
    497 
    498                     if (elements.size() == 1 && elements[0].isUnnamed()) {
    499                       // Single-value tuple is just a value.
    500                       return elements[0].disownValue();
    501                     } else {
    502                       auto result = orphanage.newOrphan<Expression>();
    503                       auto builder = result.get();
    504                       builder.adoptTuple(kj::mv(value.value));
    505                       value.copyLocationTo(builder);
    506                       return result;
    507                     }
    508                   }),
    509               p::transformWithLocation(p::sequence(keyword("import"), stringLiteral),
    510                   [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
    511                          Located<Text::Reader>&& filename) -> Orphan<Expression> {
    512                     auto result = orphanage.newOrphan<Expression>();
    513                     auto builder = result.get();
    514                     initLocation(location, builder);
    515                     filename.copyTo(builder.initImport());
    516                     return result;
    517                   }),
    518               p::transformWithLocation(p::sequence(keyword("embed"), stringLiteral),
    519                   [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
    520                          Located<Text::Reader>&& filename) -> Orphan<Expression> {
    521                     auto result = orphanage.newOrphan<Expression>();
    522                     auto builder = result.get();
    523                     initLocation(location, builder);
    524                     filename.copyTo(builder.initEmbed());
    525                     return result;
    526                   }),
    527               p::transformWithLocation(p::sequence(op("."), identifier),
    528                   [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
    529                          Located<Text::Reader>&& name) -> Orphan<Expression> {
    530                     auto result = orphanage.newOrphan<Expression>();
    531                     auto builder = result.get();
    532                     initLocation(location, builder);
    533                     name.copyTo(builder.initAbsoluteName());
    534                     return result;
    535                   }),
    536               p::transform(identifier,
    537                   [this](Located<Text::Reader>&& name) -> Orphan<Expression> {
    538                     auto result = orphanage.newOrphan<Expression>();
    539                     auto builder = result.get();
    540                     name.copyTo(builder.initRelativeName());
    541                     name.copyLocationTo(builder);
    542                     return result;
    543                   })),
    544           // Suffixes, e.g. ".member" or "(param1, param2)".
    545           p::many(p::oneOf(
    546               p::transformWithLocation(p::sequence(op("."), identifier),
    547                   [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
    548                          Located<Text::Reader>&& name) -> Orphan<Expression> {
    549                     auto result = orphanage.newOrphan<Expression>();
    550                     auto builder = result.get();
    551                     initLocation(location, builder);
    552                     name.copyTo(builder.initMember().initName());
    553                     return result;
    554                   }),
    555               p::transform(tuple,
    556                   [this](Located<Orphan<List<Expression::Param>>>&& params) -> Orphan<Expression> {
    557                     auto result = orphanage.newOrphan<Expression>();
    558                     auto builder = result.get();
    559                     params.copyLocationTo(builder);
    560                     builder.initApplication().adoptParams(kj::mv(params.value));
    561                     return result;
    562                   })))),
    563       [](Orphan<Expression>&& base, kj::Array<Orphan<Expression>>&& suffixes)
    564           -> Orphan<Expression> {
    565         // Apply all the suffixes to the base expression.
    566         uint startByte = base.getReader().getStartByte();
    567         for (auto& suffix: suffixes) {
    568           auto builder = suffix.get();
    569           if (builder.isApplication()) {
    570             builder.getApplication().adoptFunction(kj::mv(base));
    571           } else if (builder.isMember()) {
    572             builder.getMember().adoptParent(kj::mv(base));
    573           } else {
    574             KJ_FAIL_ASSERT("Unknown suffix?", (uint)builder.which());
    575           }
    576           builder.setStartByte(startByte);
    577           base = kj::mv(suffix);
    578         }
    579         return kj::mv(base);
    580       }));
    581 
    582   parsers.annotation = arena.copy(p::transform(
    583       p::sequence(op("$"), parsers.expression),
    584       [this](Orphan<Expression>&& expression)
    585           -> Orphan<Declaration::AnnotationApplication> {
    586         auto result = orphanage.newOrphan<Declaration::AnnotationApplication>();
    587         auto builder = result.get();
    588 
    589         auto exp = expression.get();
    590         if (exp.isApplication()) {
    591           // Oops, this annotation specifies the value, but we parsed it as an application on
    592           // the preceding expression. Pull it back apart.
    593           auto app = exp.getApplication();
    594           builder.adoptName(app.disownFunction());
    595           auto params = app.getParams();
    596           if (params.size() == 1 && params[0].isUnnamed()) {
    597             // Params has a single unnamed element, so reduce it to a simple value rather than
    598             // a tuple.
    599             builder.getValue().adoptExpression(params[0].disownValue());
    600           } else {
    601             // Params is not a single unnamed element, so it's a tuple.
    602             builder.getValue().initExpression().adoptTuple(app.disownParams());
    603           }
    604         } else {
    605           // The annotation has no value.
    606           builder.adoptName(kj::mv(expression));
    607           builder.getValue().setNone();
    608         }
    609 
    610         return result;
    611       }));
    612 
    613   parsers.uid = arena.copy(p::transform(
    614       p::sequence(op("@"), integerLiteral),
    615       [this](Located<uint64_t>&& value) {
    616         if (value.value < (1ull << 63)) {
    617           errorReporter.addError(value.startByte, value.endByte,
    618               "Invalid ID.  Please generate a new one with 'capnpc -i'.");
    619         }
    620         return value.asProto<LocatedInteger>(orphanage);
    621       }));
    622 
    623   parsers.ordinal = arena.copy(p::transform(
    624       p::sequence(op("@"), integerLiteral),
    625       [this](Located<uint64_t>&& value) {
    626         if (value.value >= 65536) {
    627           errorReporter.addError(value.startByte, value.endByte,
    628               "Ordinals cannot be greater than 65535.");
    629         }
    630         return value.asProto<LocatedInteger>(orphanage);
    631       }));
    632 
    633   // -----------------------------------------------------------------
    634 
    635   parsers.usingDecl = arena.copy(p::transform(
    636       p::sequence(keyword("using"), p::optional(p::sequence(identifier, op("="))),
    637                   parsers.expression),
    638       [this](kj::Maybe<Located<Text::Reader>>&& name, Orphan<Expression>&& target)
    639           -> DeclParserResult {
    640         auto decl = orphanage.newOrphan<Declaration>();
    641         auto builder = decl.get();
    642         KJ_IF_MAYBE(n, name) {
    643           n->copyTo(builder.initName());
    644         } else {
    645           auto targetReader = target.getReader();
    646           if (targetReader.isMember()) {
    647             builder.setName(targetReader.getMember().getName());
    648           } else {
    649             errorReporter.addErrorOn(targetReader,
    650                 "'using' declaration without '=' must specify a named declaration from a "
    651                 "different scope.");
    652           }
    653         }
    654         // no id, no annotations for using decl
    655         builder.initUsing().adoptTarget(kj::mv(target));
    656         return DeclParserResult(kj::mv(decl));
    657       }));
    658 
    659   parsers.constDecl = arena.copy(p::transform(
    660       p::sequence(keyword("const"), identifier, p::optional(parsers.uid),
    661                   op(":"), parsers.expression,
    662                   op("="), parsers.expression,
    663                   p::many(parsers.annotation)),
    664       [this](Located<Text::Reader>&& name, kj::Maybe<Orphan<LocatedInteger>>&& id,
    665              Orphan<Expression>&& type, Orphan<Expression>&& value,
    666              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    667                  -> DeclParserResult {
    668         auto decl = orphanage.newOrphan<Declaration>();
    669         auto builder =
    670             initDecl(decl.get(), kj::mv(name), kj::mv(id), nullptr,
    671                      kj::mv(annotations)).initConst();
    672         builder.adoptType(kj::mv(type));
    673         builder.adoptValue(kj::mv(value));
    674         return DeclParserResult(kj::mv(decl));
    675       }));
    676 
    677   parsers.enumDecl = arena.copy(p::transform(
    678       p::sequence(keyword("enum"), identifier, p::optional(parsers.uid),
    679                   p::many(parsers.annotation)),
    680       [this](Located<Text::Reader>&& name, kj::Maybe<Orphan<LocatedInteger>>&& id,
    681              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    682                  -> DeclParserResult {
    683         auto decl = orphanage.newOrphan<Declaration>();
    684         initDecl(decl.get(), kj::mv(name), kj::mv(id), nullptr, kj::mv(annotations)).setEnum();
    685         return DeclParserResult(kj::mv(decl), parsers.enumLevelDecl);
    686       }));
    687 
    688   parsers.enumerantDecl = arena.copy(p::transform(
    689       p::sequence(identifier, parsers.ordinal, p::many(parsers.annotation)),
    690       [this](Located<Text::Reader>&& name, Orphan<LocatedInteger>&& ordinal,
    691              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    692                  -> DeclParserResult {
    693         auto decl = orphanage.newOrphan<Declaration>();
    694         initMemberDecl(decl.get(), kj::mv(name), kj::mv(ordinal), kj::mv(annotations))
    695             .setEnumerant();
    696         return DeclParserResult(kj::mv(decl));
    697       }));
    698 
    699   parsers.structDecl = arena.copy(p::transform(
    700       p::sequence(keyword("struct"), identifier, p::optional(parsers.uid),
    701                   p::optional(parenthesizedList(identifier, errorReporter)),
    702                   p::many(parsers.annotation)),
    703       [this](Located<Text::Reader>&& name, kj::Maybe<Orphan<LocatedInteger>>&& id,
    704              kj::Maybe<Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>>&& genericParameters,
    705              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    706                  -> DeclParserResult {
    707         auto decl = orphanage.newOrphan<Declaration>();
    708         initDecl(decl.get(), kj::mv(name), kj::mv(id), kj::mv(genericParameters),
    709                  kj::mv(annotations)).setStruct();
    710         return DeclParserResult(kj::mv(decl), parsers.structLevelDecl);
    711       }));
    712 
    713   parsers.fieldDecl = arena.copy(p::transform(
    714       p::sequence(identifier, parsers.ordinal, op(":"), parsers.expression,
    715                   p::optional(p::sequence(op("="), parsers.expression)),
    716                   p::many(parsers.annotation)),
    717       [this](Located<Text::Reader>&& name, Orphan<LocatedInteger>&& ordinal,
    718              Orphan<Expression>&& type, kj::Maybe<Orphan<Expression>>&& defaultValue,
    719              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    720                  -> DeclParserResult {
    721         auto decl = orphanage.newOrphan<Declaration>();
    722         auto builder =
    723             initMemberDecl(decl.get(), kj::mv(name), kj::mv(ordinal), kj::mv(annotations))
    724                 .initField();
    725         builder.adoptType(kj::mv(type));
    726         KJ_IF_MAYBE(val, defaultValue) {
    727           builder.getDefaultValue().adoptValue(kj::mv(*val));
    728         } else {
    729           builder.getDefaultValue().setNone();
    730         }
    731         return DeclParserResult(kj::mv(decl));
    732       }));
    733 
    734   // Parse an ordinal followed by an optional colon, or no ordinal but require a colon.
    735   auto& ordinalOrColon = arena.copy(p::oneOf(
    736       p::transform(p::sequence(parsers.ordinal, p::optional(op("!")), p::optional(op(":"))),
    737           [](Orphan<LocatedInteger>&& ordinal,
    738                  kj::Maybe<kj::Tuple<>> exclamation,
    739                  kj::Maybe<kj::Tuple<>> colon)
    740                    -> kj::Tuple<kj::Maybe<Orphan<LocatedInteger>>, bool, bool> {
    741             return kj::tuple(kj::mv(ordinal), exclamation == nullptr, colon == nullptr);
    742           }),
    743       p::transform(op(":"),
    744           []() -> kj::Tuple<kj::Maybe<Orphan<LocatedInteger>>, bool, bool> {
    745             return kj::tuple(nullptr, false, false);
    746           })));
    747 
    748   parsers.unionDecl = arena.copy(p::transform(
    749       // The first branch of this oneOf() matches named unions.  The second branch matches unnamed
    750       // unions and generates dummy values for the parse results.
    751       p::oneOf(
    752           p::sequence(
    753               identifier, ordinalOrColon,
    754               keyword("union"), p::many(parsers.annotation)),
    755           p::transformWithLocation(p::sequence(keyword("union"), p::endOfInput),
    756               [](kj::parse::Span<List<Token>::Reader::Iterator> location) {
    757                 return kj::tuple(
    758                     Located<Text::Reader>("", location.begin()->getStartByte(),
    759                                           location.begin()->getEndByte()),
    760                     kj::Maybe<Orphan<LocatedInteger>>(nullptr),
    761                     false, false,
    762                     kj::Array<Orphan<Declaration::AnnotationApplication>>(nullptr));
    763               })),
    764       [this](Located<Text::Reader>&& name,
    765              kj::Maybe<Orphan<LocatedInteger>>&& ordinal,
    766              bool missingExclamation, bool missingColon,
    767              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    768                  -> DeclParserResult {
    769         if (missingExclamation) {
    770           errorReporter.addErrorOn(KJ_ASSERT_NONNULL(ordinal).getReader(),
    771               "As of Cap'n Proto v0.3, it is no longer necessary to assign numbers to "
    772               "unions. However, removing the number will break binary compatibility. "
    773               "If this is an old protocol and you need to retain compatibility, please "
    774               "add an exclamation point after the number to indicate that it is really "
    775               "needed, e.g. `foo @1! :union {`. If this is a new protocol or compatibility "
    776               "doesn't matter, just remove the @n entirely. Sorry for the inconvenience, "
    777               "and thanks for being an early adopter!  :)");
    778         }
    779         if (missingColon) {
    780           errorReporter.addErrorOn(KJ_ASSERT_NONNULL(ordinal).getReader(),
    781               "As of Cap'n Proto v0.3, the 'union' keyword should be prefixed with a colon "
    782               "for named unions, e.g. `foo :union {`.");
    783         }
    784 
    785         auto decl = orphanage.newOrphan<Declaration>();
    786         auto builder = decl.get();
    787         name.copyTo(builder.initName());
    788         KJ_IF_MAYBE(ord, ordinal) {
    789           builder.getId().adoptOrdinal(kj::mv(*ord));
    790         } else {
    791           builder.getId().setUnspecified();
    792         }
    793         auto list = builder.initAnnotations(annotations.size());
    794         for (uint i = 0; i < annotations.size(); i++) {
    795           list.adoptWithCaveats(i, kj::mv(annotations[i]));
    796         }
    797         builder.setUnion();
    798         return DeclParserResult(kj::mv(decl), parsers.structLevelDecl);
    799       }));
    800 
    801   parsers.groupDecl = arena.copy(p::transform(
    802       p::sequence(identifier, op(":"), keyword("group"), p::many(parsers.annotation)),
    803       [this](Located<Text::Reader>&& name,
    804              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    805                  -> DeclParserResult {
    806         auto decl = orphanage.newOrphan<Declaration>();
    807         auto builder = decl.get();
    808         name.copyTo(builder.getName());
    809         builder.getId().setUnspecified();
    810         auto list = builder.initAnnotations(annotations.size());
    811         for (uint i = 0; i < annotations.size(); i++) {
    812           list.adoptWithCaveats(i, kj::mv(annotations[i]));
    813         }
    814         builder.setGroup();
    815         return DeclParserResult(kj::mv(decl), parsers.structLevelDecl);
    816       }));
    817 
    818   parsers.interfaceDecl = arena.copy(p::transform(
    819       p::sequence(keyword("interface"), identifier, p::optional(parsers.uid),
    820                   p::optional(parenthesizedList(identifier, errorReporter)),
    821                   p::optional(p::sequence(
    822                       keyword("extends"), parenthesizedList(parsers.expression, errorReporter))),
    823                   p::many(parsers.annotation)),
    824       [this](Located<Text::Reader>&& name, kj::Maybe<Orphan<LocatedInteger>>&& id,
    825              kj::Maybe<Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>>&& genericParameters,
    826              kj::Maybe<Located<kj::Array<kj::Maybe<Orphan<Expression>>>>>&& superclasses,
    827              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    828                  -> DeclParserResult {
    829         auto decl = orphanage.newOrphan<Declaration>();
    830         auto builder = initDecl(
    831             decl.get(), kj::mv(name), kj::mv(id), kj::mv(genericParameters),
    832             kj::mv(annotations)).initInterface();
    833         KJ_IF_MAYBE(s, superclasses) {
    834           auto superclassesBuilder = builder.initSuperclasses(s->value.size());
    835           for (uint i: kj::indices(s->value)) {
    836             KJ_IF_MAYBE(superclass, s->value[i]) {
    837               superclassesBuilder.adoptWithCaveats(i, kj::mv(*superclass));
    838             }
    839           }
    840         }
    841         return DeclParserResult(kj::mv(decl), parsers.interfaceLevelDecl);
    842       }));
    843 
    844   parsers.param = arena.copy(p::transformWithLocation(
    845       p::sequence(identifier, op(":"), parsers.expression,
    846                   p::optional(p::sequence(op("="), parsers.expression)),
    847                   p::many(parsers.annotation)),
    848       [this](kj::parse::Span<List<Token>::Reader::Iterator> location,
    849              Located<Text::Reader>&& name, Orphan<Expression>&& type,
    850              kj::Maybe<Orphan<Expression>>&& defaultValue,
    851              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    852                  -> Orphan<Declaration::Param> {
    853         auto result = orphanage.newOrphan<Declaration::Param>();
    854         auto builder = result.get();
    855 
    856         initLocation(location, builder);
    857 
    858         name.copyTo(builder.initName());
    859         builder.adoptType(kj::mv(type));
    860         builder.adoptAnnotations(arrayToList(orphanage, kj::mv(annotations)));
    861         KJ_IF_MAYBE(val, defaultValue) {
    862           builder.getDefaultValue().adoptValue(kj::mv(*val));
    863         } else {
    864           builder.getDefaultValue().setNone();
    865         }
    866 
    867         return kj::mv(result);
    868       }));
    869 
    870   auto& paramList = arena.copy(p::oneOf(
    871       p::transform(parenthesizedList(parsers.param, errorReporter),
    872           [this](Located<kj::Array<kj::Maybe<Orphan<Declaration::Param>>>>&& params)
    873                 -> Orphan<Declaration::ParamList> {
    874             auto decl = orphanage.newOrphan<Declaration::ParamList>();
    875             auto builder = decl.get();
    876             params.copyLocationTo(builder);
    877             auto listBuilder = builder.initNamedList(params.value.size());
    878             for (uint i: kj::indices(params.value)) {
    879               KJ_IF_MAYBE(param, params.value[i]) {
    880                 listBuilder.adoptWithCaveats(i, kj::mv(*param));
    881               }
    882             }
    883             return decl;
    884           }),
    885       p::transform(locatedKeyword("stream"),
    886           [this](Located<Text::Reader>&& kw) -> Orphan<Declaration::ParamList> {
    887             auto decl = orphanage.newOrphan<Declaration::ParamList>();
    888             auto builder = decl.get();
    889             kw.copyLocationTo(builder);
    890             builder.setStream();
    891             return decl;
    892           }),
    893       p::transform(parsers.expression,
    894           [this](Orphan<Expression>&& name) -> Orphan<Declaration::ParamList> {
    895             auto decl = orphanage.newOrphan<Declaration::ParamList>();
    896             auto builder = decl.get();
    897             auto nameReader = name.getReader();
    898             builder.setStartByte(nameReader.getStartByte());
    899             builder.setEndByte(nameReader.getEndByte());
    900             builder.adoptType(kj::mv(name));
    901             return decl;
    902           })));
    903 
    904   parsers.methodDecl = arena.copy(p::transform(
    905       p::sequence(identifier, parsers.ordinal,
    906                   p::optional(bracketedList(identifier, errorReporter)),
    907                   paramList,
    908                   p::optional(p::sequence(op("->"), paramList)),
    909                   p::many(parsers.annotation)),
    910       [this](Located<Text::Reader>&& name, Orphan<LocatedInteger>&& ordinal,
    911              kj::Maybe<Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>>&& genericParams,
    912              Orphan<Declaration::ParamList>&& params,
    913              kj::Maybe<Orphan<Declaration::ParamList>>&& results,
    914              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    915                  -> DeclParserResult {
    916         auto decl = orphanage.newOrphan<Declaration>();
    917         auto nodeBuilder = initMemberDecl(
    918             decl.get(), kj::mv(name), kj::mv(ordinal), kj::mv(annotations));
    919 
    920         initGenericParams(nodeBuilder, kj::mv(genericParams));
    921 
    922         auto builder = nodeBuilder.initMethod();
    923 
    924         builder.adoptParams(kj::mv(params));
    925 
    926         KJ_IF_MAYBE(r, results) {
    927           builder.getResults().adoptExplicit(kj::mv(*r));
    928         } else {
    929           builder.getResults().setNone();
    930         }
    931 
    932         return DeclParserResult(kj::mv(decl));
    933       }));
    934 
    935   auto& annotationTarget = arena.copy(p::oneOf(
    936       identifier,
    937       p::transformWithLocation(op("*"),
    938           [](kj::parse::Span<List<Token>::Reader::Iterator> location) {
    939             // Hacky...
    940             return Located<Text::Reader>("*",
    941                 location.begin()->getStartByte(),
    942                 location.begin()->getEndByte());
    943           })));
    944 
    945   parsers.annotationDecl = arena.copy(p::transform(
    946       p::sequence(keyword("annotation"), identifier, p::optional(parsers.uid),
    947                   parenthesizedList(annotationTarget, errorReporter),
    948                   op(":"), parsers.expression,
    949                   p::many(parsers.annotation)),
    950       [this](Located<Text::Reader>&& name, kj::Maybe<Orphan<LocatedInteger>>&& id,
    951              Located<kj::Array<kj::Maybe<Located<Text::Reader>>>>&& targets,
    952              Orphan<Expression>&& type,
    953              kj::Array<Orphan<Declaration::AnnotationApplication>>&& annotations)
    954                  -> DeclParserResult {
    955         auto decl = orphanage.newOrphan<Declaration>();
    956         auto builder =
    957             initDecl(decl.get(), kj::mv(name), kj::mv(id), nullptr,
    958                      kj::mv(annotations)).initAnnotation();
    959         builder.adoptType(kj::mv(type));
    960         DynamicStruct::Builder dynamicBuilder = builder;
    961         for (auto& maybeTarget: targets.value) {
    962           KJ_IF_MAYBE(target, maybeTarget) {
    963             if (target->value == "*") {
    964               // Set all.
    965               if (targets.value.size() > 1) {
    966                 errorReporter.addError(target->startByte, target->endByte,
    967                     "Wildcard should not be specified together with other targets.");
    968               }
    969 
    970               for (auto field: dynamicBuilder.getSchema().getFields()) {
    971                 if (field.getProto().getName().startsWith("targets")) {
    972                   dynamicBuilder.set(field, true);
    973                 }
    974               }
    975             } else {
    976               if (target->value.size() == 0 || target->value.size() >= 32 ||
    977                   target->value[0] < 'a' || target->value[0] > 'z') {
    978                 errorReporter.addError(target->startByte, target->endByte,
    979                                        "Not a valid annotation target.");
    980               } else {
    981                 char buffer[64];
    982                 strcpy(buffer, "targets");
    983                 strcat(buffer, target->value.cStr());
    984                 buffer[strlen("targets")] += 'A' - 'a';
    985                 KJ_IF_MAYBE(field, dynamicBuilder.getSchema().findFieldByName(buffer)) {
    986                   if (dynamicBuilder.get(*field).as<bool>()) {
    987                     errorReporter.addError(target->startByte, target->endByte,
    988                                            "Duplicate target specification.");
    989                   }
    990                   dynamicBuilder.set(*field, true);
    991                 } else {
    992                   errorReporter.addError(target->startByte, target->endByte,
    993                                          "Not a valid annotation target.");
    994                 }
    995               }
    996             }
    997           }
    998         }
    999         return DeclParserResult(kj::mv(decl));
   1000       }));
   1001 
   1002   // -----------------------------------------------------------------
   1003 
   1004   auto& nakedId = arena.copy(p::transform(parsers.uid,
   1005       [this](Orphan<LocatedInteger>&& value) -> DeclParserResult {
   1006         auto decl = orphanage.newOrphan<Declaration>();
   1007         decl.get().adoptNakedId(kj::mv(value));
   1008         return DeclParserResult(kj::mv(decl));
   1009       }));
   1010 
   1011   auto& nakedAnnotation = arena.copy(p::transform(parsers.annotation,
   1012       [this](Orphan<Declaration::AnnotationApplication>&& value) -> DeclParserResult {
   1013         auto decl = orphanage.newOrphan<Declaration>();
   1014         decl.get().adoptNakedAnnotation(kj::mv(value));
   1015         return DeclParserResult(kj::mv(decl));
   1016       }));
   1017 
   1018   // -----------------------------------------------------------------
   1019 
   1020   parsers.genericDecl = arena.copy(p::oneOf(
   1021       parsers.usingDecl, parsers.constDecl, parsers.annotationDecl,
   1022       parsers.enumDecl, parsers.structDecl, parsers.interfaceDecl));
   1023   parsers.fileLevelDecl = arena.copy(p::oneOf(
   1024       parsers.genericDecl, nakedId, nakedAnnotation));
   1025   parsers.enumLevelDecl = arena.copy(p::oneOf(parsers.enumerantDecl));
   1026   parsers.structLevelDecl = arena.copy(p::oneOf(
   1027       parsers.unionDecl, parsers.fieldDecl, parsers.groupDecl, parsers.genericDecl));
   1028   parsers.interfaceLevelDecl = arena.copy(p::oneOf(
   1029       parsers.methodDecl, parsers.genericDecl));
   1030 }
   1031 
   1032 CapnpParser::~CapnpParser() noexcept(false) {}
   1033 
   1034 kj::Maybe<Orphan<Declaration>> CapnpParser::parseStatement(
   1035     Statement::Reader statement, const DeclParser& parser) {
   1036   auto fullParser = p::sequence(parser, p::endOfInput);
   1037 
   1038   auto tokens = statement.getTokens();
   1039   ParserInput parserInput(tokens.begin(), tokens.end());
   1040 
   1041   KJ_IF_MAYBE(output, fullParser(parserInput)) {
   1042     auto builder = output->decl.get();
   1043 
   1044     if (statement.hasDocComment()) {
   1045       builder.setDocComment(statement.getDocComment());
   1046     }
   1047 
   1048     builder.setStartByte(statement.getStartByte());
   1049     builder.setEndByte(statement.getEndByte());
   1050 
   1051     switch (statement.which()) {
   1052       case Statement::LINE:
   1053         if (output->memberParser != nullptr) {
   1054           errorReporter.addError(statement.getStartByte(), statement.getEndByte(),
   1055               "This statement should end with a block, not a semicolon.");
   1056         }
   1057         break;
   1058 
   1059       case Statement::BLOCK:
   1060         KJ_IF_MAYBE(memberParser, output->memberParser) {
   1061           auto memberStatements = statement.getBlock();
   1062           kj::Vector<Orphan<Declaration>> members(memberStatements.size());
   1063           for (auto memberStatement: memberStatements) {
   1064             KJ_IF_MAYBE(member, parseStatement(memberStatement, *memberParser)) {
   1065               members.add(kj::mv(*member));
   1066             }
   1067           }
   1068           builder.adoptNestedDecls(arrayToList(orphanage, members.releaseAsArray()));
   1069         } else {
   1070           errorReporter.addError(statement.getStartByte(), statement.getEndByte(),
   1071               "This statement should end with a semicolon, not a block.");
   1072         }
   1073         break;
   1074     }
   1075 
   1076     return kj::mv(output->decl);
   1077 
   1078   } else {
   1079     // Parse error.  Figure out where to report it.
   1080     auto best = parserInput.getBest();
   1081     uint32_t bestByte;
   1082 
   1083     if (best != tokens.end()) {
   1084       bestByte = best->getStartByte();
   1085     } else if (tokens.end() != tokens.begin()) {
   1086       bestByte = (tokens.end() - 1)->getEndByte();
   1087     } else {
   1088       bestByte = statement.getStartByte();
   1089     }
   1090 
   1091     errorReporter.addError(bestByte, bestByte, "Parse error.");
   1092     return nullptr;
   1093   }
   1094 }
   1095 
   1096 // =======================================================================================
   1097 
   1098 static const char HEXDIGITS[] = "0123456789abcdef";
   1099 
   1100 static kj::StringTree stringLiteralStringTree(kj::StringPtr chars) {
   1101   return kj::strTree('"', kj::encodeCEscape(chars), '"');
   1102 }
   1103 
   1104 static kj::StringTree binaryLiteralStringTree(Data::Reader data) {
   1105   kj::Vector<char> escaped(data.size() * 3);
   1106 
   1107   for (byte b: data) {
   1108     escaped.add(HEXDIGITS[b % 16]);
   1109     escaped.add(HEXDIGITS[b / 16]);
   1110     escaped.add(' ');
   1111   }
   1112 
   1113   escaped.removeLast();
   1114   return kj::strTree("0x\"", escaped, '"');
   1115 }
   1116 
   1117 static kj::StringTree expressionStringTree(Expression::Reader exp);
   1118 
   1119 static kj::StringTree tupleLiteral(List<Expression::Param>::Reader params) {
   1120   auto parts = kj::heapArrayBuilder<kj::StringTree>(params.size());
   1121   for (auto param: params) {
   1122     auto part = expressionStringTree(param.getValue());
   1123     if (param.isNamed()) {
   1124       part = kj::strTree(param.getNamed().getValue(), " = ", kj::mv(part));
   1125     }
   1126     parts.add(kj::mv(part));
   1127   }
   1128   return kj::strTree("( ", kj::StringTree(parts.finish(), ", "), " )");
   1129 }
   1130 
   1131 static kj::StringTree expressionStringTree(Expression::Reader exp) {
   1132   switch (exp.which()) {
   1133     case Expression::UNKNOWN:
   1134       return kj::strTree("<parse error>");
   1135     case Expression::POSITIVE_INT:
   1136       return kj::strTree(exp.getPositiveInt());
   1137     case Expression::NEGATIVE_INT:
   1138       return kj::strTree('-', exp.getNegativeInt());
   1139     case Expression::FLOAT:
   1140       return kj::strTree(exp.getFloat());
   1141     case Expression::STRING:
   1142       return stringLiteralStringTree(exp.getString());
   1143     case Expression::BINARY:
   1144       return binaryLiteralStringTree(exp.getBinary());
   1145     case Expression::RELATIVE_NAME:
   1146       return kj::strTree(exp.getRelativeName().getValue());
   1147     case Expression::ABSOLUTE_NAME:
   1148       return kj::strTree('.', exp.getAbsoluteName().getValue());
   1149     case Expression::IMPORT:
   1150       return kj::strTree("import ", stringLiteralStringTree(exp.getImport().getValue()));
   1151     case Expression::EMBED:
   1152       return kj::strTree("embed ", stringLiteralStringTree(exp.getEmbed().getValue()));
   1153 
   1154     case Expression::LIST: {
   1155       auto list = exp.getList();
   1156       auto parts = kj::heapArrayBuilder<kj::StringTree>(list.size());
   1157       for (auto element: list) {
   1158         parts.add(expressionStringTree(element));
   1159       }
   1160       return kj::strTree("[ ", kj::StringTree(parts.finish(), ", "), " ]");
   1161     }
   1162 
   1163     case Expression::TUPLE:
   1164       return tupleLiteral(exp.getTuple());
   1165 
   1166     case Expression::APPLICATION: {
   1167       auto app = exp.getApplication();
   1168       return kj::strTree(expressionStringTree(app.getFunction()),
   1169                          '(', tupleLiteral(app.getParams()), ')');
   1170     }
   1171 
   1172     case Expression::MEMBER: {
   1173       auto member = exp.getMember();
   1174       return kj::strTree(expressionStringTree(member.getParent()), '.',
   1175                          member.getName().getValue());
   1176     }
   1177   }
   1178 
   1179   KJ_UNREACHABLE;
   1180 }
   1181 
   1182 kj::String expressionString(Expression::Reader name) {
   1183   return expressionStringTree(name).flatten();
   1184 }
   1185 
   1186 }  // namespace compiler
   1187 }  // namespace capnp