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
//
18
17
#ifndef SWIFT_LOCALIZATIONFORMAT_H
19
18
#define SWIFT_LOCALIZATIONFORMAT_H
20
19
20
+ #include " llvm/ADT/Hashing.h"
21
+ #include " llvm/ADT/STLExtras.h"
21
22
#include " llvm/ADT/StringRef.h"
23
+ #include " llvm/Bitstream/BitstreamReader.h"
24
+ #include " llvm/Support/EndianStream.h"
25
+ #include " llvm/Support/MemoryBuffer.h"
26
+ #include " llvm/Support/OnDiskHashTable.h"
22
27
#include " llvm/Support/YAMLParser.h"
23
28
#include " llvm/Support/YAMLTraits.h"
29
+ #include " llvm/Support/raw_ostream.h"
30
+ #include < cstdint>
31
+ #include < memory>
24
32
#include < string>
25
33
#include < type_traits>
34
+ #include < utility>
35
+ #include < vector>
26
36
27
37
namespace swift {
28
38
enum class DiagID : uint32_t ;
29
39
30
40
namespace diag {
41
+ using namespace llvm ::support;
42
+
43
+ class LocalizationWriterInfo {
44
+ public:
45
+ using key_type = uint32_t ;
46
+ using key_type_ref = const uint32_t &;
47
+ using data_type = std::string;
48
+ using data_type_ref = llvm::StringRef;
49
+ using hash_value_type = uint32_t ;
50
+ using offset_type = uint32_t ;
51
+
52
+ hash_value_type ComputeHash (key_type_ref key) { return llvm::hash_code (key); }
53
+
54
+ std::pair<offset_type, offset_type> EmitKeyDataLength (llvm::raw_ostream &out,
55
+ key_type_ref key,
56
+ data_type_ref data) {
57
+ offset_type dataLength = static_cast <offset_type>(data.size ());
58
+ endian::write<offset_type>(out, dataLength, little);
59
+ // No need to write the key length; it's constant.
60
+ return {sizeof (key_type), dataLength};
61
+ }
62
+
63
+ void EmitKey (llvm::raw_ostream &out, key_type_ref key, unsigned len) {
64
+ assert (len == sizeof (key_type));
65
+ endian::write<key_type>(out, key, little);
66
+ }
67
+
68
+ void EmitData (llvm::raw_ostream &out, key_type_ref key, data_type_ref data,
69
+ unsigned len) {
70
+ out << data;
71
+ }
72
+ };
73
+
74
+ class LocalizationReaderInfo {
75
+ public:
76
+ using internal_key_type = uint32_t ;
77
+ using external_key_type = swift::DiagID;
78
+ using data_type = llvm::StringRef;
79
+ using hash_value_type = uint32_t ;
80
+ using offset_type = uint32_t ;
81
+
82
+ internal_key_type GetInternalKey (external_key_type key) {
83
+ return static_cast <internal_key_type>(key);
84
+ }
85
+
86
+ external_key_type GetExternalKey (internal_key_type key) {
87
+ return static_cast <external_key_type>(key);
88
+ }
89
+
90
+ static bool EqualKey (internal_key_type lhs, internal_key_type rhs) {
91
+ return lhs == rhs;
92
+ }
93
+
94
+ hash_value_type ComputeHash (internal_key_type key) {
95
+ return llvm::hash_code (key);
96
+ }
97
+
98
+ static std::pair<offset_type, offset_type>
99
+ ReadKeyDataLength (const unsigned char *&data) {
100
+ offset_type dataLength =
101
+ endian::readNext<offset_type, little, unaligned>(data);
102
+ return {sizeof (uint32_t ), dataLength};
103
+ }
104
+
105
+ internal_key_type ReadKey (const unsigned char *data, offset_type length) {
106
+ return endian::readNext<internal_key_type, little, unaligned>(data);
107
+ }
108
+
109
+ data_type ReadData (internal_key_type Key, const unsigned char *data,
110
+ offset_type length) {
111
+ return data_type ((const char *)data, length);
112
+ }
113
+ };
114
+
115
+ class SerializedLocalizationWriter {
116
+ using offset_type = LocalizationWriterInfo::offset_type;
117
+ llvm::OnDiskChainedHashTableGenerator<LocalizationWriterInfo> generator;
118
+
119
+ public:
120
+ // / Enqueue the given diagnostic to be included in a serialized translations
121
+ // / file.
122
+ // /
123
+ // / \param id The identifier associated with the given diagnostic message e.g.
124
+ // / 'cannot_convert_argument'.
125
+ // / \param translation The localized diagnostic message for the given
126
+ // / identifier.
127
+ void insert (swift::DiagID id, llvm::StringRef translation);
128
+
129
+ // / Write out previously inserted diagnostic translations into the given
130
+ // / location.
131
+ // /
132
+ // / \param filePath The location of the serialized diagnostics file. It's
133
+ // / supposed to be a file with '.db' postfix.
134
+ // / \returns true if all diagnostic
135
+ // / messages have been successfully serialized, false otherwise.
136
+ bool emit (llvm::StringRef filePath);
137
+ };
138
+
31
139
class LocalizationProducer {
32
140
public:
33
141
// / If the message isn't available/localized in the current `yaml` file,
@@ -41,9 +149,31 @@ class LocalizationProducer {
41
149
};
42
150
43
151
class YAMLLocalizationProducer final : public LocalizationProducer {
44
- public:
45
152
std::vector<std::string> diagnostics;
46
- explicit YAMLLocalizationProducer (std::string locale, std::string path);
153
+
154
+ public:
155
+ explicit YAMLLocalizationProducer (llvm::StringRef filePath);
156
+ llvm::StringRef getMessageOr (swift::DiagID id,
157
+ llvm::StringRef defaultMessage) const override ;
158
+
159
+ // / Iterate over all of the available (non-empty) translations
160
+ // / maintained by this producer, callback gets each translation
161
+ // / with its unique identifier.
162
+ void forEachAvailable (
163
+ llvm::function_ref<void (swift::DiagID, llvm::StringRef)> callback) const ;
164
+ };
165
+
166
+ class SerializedLocalizationProducer final : public LocalizationProducer {
167
+ using SerializedLocalizationTable =
168
+ llvm::OnDiskIterableChainedHashTable<LocalizationReaderInfo>;
169
+ using offset_type = LocalizationReaderInfo::offset_type;
170
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
171
+ std::unique_ptr<SerializedLocalizationTable> SerializedTable;
172
+
173
+ public:
174
+ explicit SerializedLocalizationProducer (
175
+ std::unique_ptr<llvm::MemoryBuffer> buffer);
176
+
47
177
llvm::StringRef getMessageOr (swift::DiagID id,
48
178
llvm::StringRef defaultMessage) const override ;
49
179
};
0 commit comments