1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_TOKEN_H_
6 #define ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_TOKEN_H_
7 
8 #include <stdint.h>
9 
10 #include "source_location.h"
11 #include "string_view.h"
12 
13 namespace fidl {
14 
15 // A Token represents a typed view into a source buffer. That is, it
16 // has a TokenKind, and it has a buffer representing the data
17 // corresponding to the token. No processing is done on the data:
18 // string or numeric literals aren't further parsed, identifiers
19 // uniqued, and so on.
20 class Token {
21 public:
22     enum Kind : uint8_t {
23 #define TOKEN(Name) k##Name,
24 #include "fidl/token_definitions.inc"
25 #undef TOKEN
26     };
27 
28     enum Subkind : uint8_t {
29         kNone = 0,
30 #define KEYWORD(Name, Spelling) k##Name,
31 #include "fidl/token_definitions.inc"
32 #undef KEYWORD
33     };
34 
35     class KindAndSubkind {
36     public:
KindAndSubkind(Kind kind,Subkind subkind)37         constexpr KindAndSubkind(Kind kind, Subkind subkind)
38             : kind_(kind), subkind_(subkind) {}
39 
kind()40         constexpr Kind kind() const { return kind_; }
subkind()41         constexpr Subkind subkind() const { return subkind_; }
combined()42         constexpr uint16_t combined() const { return uint16_t(kind_) | uint16_t(subkind_ << 8); }
43     private:
44         Kind kind_;
45         Subkind subkind_;
46     };
47 
Token(SourceLocation previous_end,SourceLocation location,Kind kind,Subkind subkind)48     Token(SourceLocation previous_end, SourceLocation location, Kind kind, Subkind subkind)
49         : previous_end_(previous_end), location_(location), kind_and_subkind_(KindAndSubkind(kind, subkind)) {}
50 
Token()51     Token()
52         : Token(SourceLocation(), SourceLocation(), Token::Kind::kNotAToken, Token::Subkind::kNone) {}
53 
Name(KindAndSubkind kind_and_subkind)54     static const char* Name(KindAndSubkind kind_and_subkind) {
55         switch (kind_and_subkind.combined()) {
56 #define TOKEN(Name)            \
57     case Token::Kind::k##Name: \
58         return #Name;
59 #include "fidl/token_definitions.inc"
60 #undef TOKEN
61 #define KEYWORD(Name, Spelling)                                                               \
62     case Token::KindAndSubkind(Token::Kind::kIdentifier, Token::Subkind::k##Name).combined(): \
63         return #Spelling;
64 #include "fidl/token_definitions.inc"
65 #undef KEYWORD
66         default:
67             return "<unknown token>";
68         }
69     }
70 
data()71     StringView data() const { return location_.data(); }
location()72     SourceLocation location() const { return location_; }
set_previous_end(SourceLocation location)73     void set_previous_end(SourceLocation location) { previous_end_ = location; }
previous_end()74     SourceLocation previous_end() const { return previous_end_; }
kind()75     Kind kind() const { return kind_and_subkind_.kind(); }
subkind()76     Subkind subkind() const { return kind_and_subkind_.subkind(); }
kind_and_subkind()77     KindAndSubkind kind_and_subkind() const { return kind_and_subkind_; }
78 
79 private:
80     // The end of the previous token.  Everything between this and location_ is
81     // somehow uninteresting to the parser (whitespace, comments, discarded
82     // braces, etc).
83     SourceLocation previous_end_;
84     SourceLocation location_;
85     KindAndSubkind kind_and_subkind_;
86 };
87 
88 } // namespace fidl
89 
90 #endif // ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_TOKEN_H_
91