1
- // ===--- LocalizationFormat.h - YAML format for Diagnostic Messages ---*-
2
- // C++ -*-===//
1
+ // ===--- LocalizationFormat.h - Format for Diagnostic Messages --*- C++ -*-===//
3
2
//
4
3
// This source file is part of the Swift.org open source project
5
4
//
19
18
#define SWIFT_LOCALIZATIONFORMAT_H
20
19
21
20
#include " llvm/ADT/StringRef.h"
21
+ #include " llvm/Bitstream/BitstreamReader.h"
22
+ #include " llvm/Support/DJB.h"
23
+ #include " llvm/Support/MemoryBuffer.h"
24
+ #include " llvm/Support/OnDiskHashTable.h"
22
25
#include " llvm/Support/YAMLParser.h"
23
26
#include " llvm/Support/YAMLTraits.h"
24
27
#include < string>
@@ -28,6 +31,101 @@ namespace swift {
28
31
enum class DiagID : uint32_t ;
29
32
30
33
namespace diag {
34
+ using namespace llvm ::support;
35
+
36
+ class LocalizationWriterInfo {
37
+ public:
38
+ using key_type = llvm::StringRef;
39
+ using key_type_ref = key_type;
40
+ using data_type = llvm::StringRef;
41
+ using data_type_ref = data_type;
42
+ using hash_value_type = uint32_t ;
43
+ using offset_type = uint32_t ;
44
+
45
+ hash_value_type ComputeHash (key_type_ref key) { return llvm::djbHash (key); }
46
+
47
+ std::pair<unsigned , unsigned > EmitKeyDataLength (llvm::raw_ostream &out,
48
+ key_type_ref key,
49
+ data_type_ref data) {
50
+ offset_type keyLength = static_cast <offset_type>(key.size ());
51
+ offset_type dataLength = static_cast <offset_type>(data.size ());
52
+ endian::write<offset_type>(out, keyLength, little);
53
+ endian::write<offset_type>(out, dataLength, little);
54
+ return {keyLength, dataLength};
55
+ }
56
+
57
+ void EmitKey (llvm::raw_ostream &out, key_type_ref key, unsigned len) {
58
+ out << key;
59
+ }
60
+
61
+ void EmitData (llvm::raw_ostream &out, key_type_ref key, data_type_ref data,
62
+ unsigned len) {
63
+ out << data;
64
+ }
65
+ };
66
+
67
+ class LocalizationReaderInfo {
68
+ public:
69
+ using internal_key_type = llvm::StringRef;
70
+ using external_key_type = internal_key_type;
71
+ using data_type = llvm::StringRef;
72
+ using hash_value_type = uint32_t ;
73
+ using offset_type = uint32_t ;
74
+
75
+ internal_key_type GetInternalKey (external_key_type key) { return key; }
76
+
77
+ external_key_type GetExternalKey (internal_key_type key) { return key; }
78
+
79
+ static bool EqualKey (internal_key_type lhs, internal_key_type rhs) {
80
+ return lhs == rhs;
81
+ }
82
+
83
+ hash_value_type ComputeHash (internal_key_type key) {
84
+ return llvm::djbHash (key);
85
+ }
86
+
87
+ static std::pair<unsigned , unsigned > ReadKeyDataLength (const uint8_t *&data) {
88
+ offset_type keyLength =
89
+ endian::readNext<offset_type, little, unaligned>(data);
90
+ offset_type dataLength =
91
+ endian::readNext<offset_type, little, unaligned>(data);
92
+ return {keyLength, dataLength};
93
+ }
94
+
95
+ internal_key_type ReadKey (const uint8_t *data, offset_type length) {
96
+ return internal_key_type ((const char *)data, length);
97
+ }
98
+
99
+ data_type ReadData (llvm::StringRef Key, const uint8_t *data,
100
+ offset_type length) {
101
+ return data_type ((const char *)data, length);
102
+ }
103
+ };
104
+
105
+ class SerializedLocalizationWriter {
106
+ using offset_type = LocalizationWriterInfo::offset_type;
107
+ llvm::OnDiskChainedHashTableGenerator<LocalizationWriterInfo> generator;
108
+
109
+ public:
110
+ // / Enqueue the given diagnostic to be included in a serialized translations
111
+ // / file.
112
+ // /
113
+ // / \param id The identifier associated with the given diagnostic message e.g.
114
+ // / 'cannot_convert_argument'.
115
+ // / \param translation The localized diagnostic
116
+ // / message for the given identifier.
117
+ void insert (llvm::StringRef id, llvm::StringRef translation);
118
+
119
+ // / Write out previously inserted diagnostic translations into the given
120
+ // / location.
121
+ // /
122
+ // / \param filePath The location of the serialized diagnostics file. It's
123
+ // / supposed to be a file with '.db' postfix.
124
+ // / \returns true if all diagnostic
125
+ // / messages have been successfully serialized, false otherwise.
126
+ bool emit (llvm::StringRef filePath);
127
+ };
128
+
31
129
class LocalizationProducer {
32
130
public:
33
131
// / If the message isn't available/localized in the current `yaml` file,
@@ -41,9 +139,55 @@ class LocalizationProducer {
41
139
};
42
140
43
141
class YAMLLocalizationProducer final : public LocalizationProducer {
142
+ // Type of the `diagnostics` vector.
143
+ using T = std::vector<std::string>;
144
+ struct Node {
145
+ uint32_t id;
146
+ typename T::value_type &msg;
147
+ };
148
+ typedef Node value_type;
149
+
150
+ class iterator {
151
+ typename T::iterator it;
152
+ uint32_t counter;
153
+
154
+ public:
155
+ iterator (T::iterator _it, uint32_t counter = 0 )
156
+ : it(_it), counter(counter) {}
157
+
158
+ iterator operator ++() { return iterator (++it, ++counter); }
159
+
160
+ bool operator !=(iterator other) { return it != other.it ; }
161
+
162
+ typename T::iterator::value_type node () { return *it; }
163
+
164
+ value_type operator *() { return value_type{counter, *it}; }
165
+
166
+ uint32_t index () { return counter; }
167
+ };
168
+
44
169
public:
45
170
std::vector<std::string> diagnostics;
46
- explicit YAMLLocalizationProducer (std::string locale, std::string path);
171
+ explicit YAMLLocalizationProducer (llvm::StringRef filePath);
172
+ llvm::StringRef getMessageOr (swift::DiagID id,
173
+ llvm::StringRef defaultMessage) const override ;
174
+
175
+ iterator begin () { return iterator (diagnostics.begin ()); }
176
+
177
+ iterator end () { return iterator (diagnostics.end ()); }
178
+ };
179
+
180
+ class SerializedLocalizationProducer final : public LocalizationProducer {
181
+ using SerializedLocalizationTable =
182
+ llvm::OnDiskIterableChainedHashTable<LocalizationReaderInfo>;
183
+ using offset_type = LocalizationReaderInfo::offset_type;
184
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
185
+ std::unique_ptr<SerializedLocalizationTable> SerializedTable;
186
+
187
+ public:
188
+ explicit SerializedLocalizationProducer (
189
+ std::unique_ptr<llvm::MemoryBuffer> buffer);
190
+
47
191
llvm::StringRef getMessageOr (swift::DiagID id,
48
192
llvm::StringRef defaultMessage) const override ;
49
193
};
0 commit comments