5
5
#include < mp/config.h>
6
6
#include < mp/util.h>
7
7
8
- #include < boost/optional.hpp >
8
+ #include < algorithm >
9
9
#include < capnp/schema-parser.h>
10
10
#include < fstream>
11
11
#include < map>
12
12
#include < set>
13
13
#include < sstream>
14
+ #include < unistd.h>
14
15
#include < vector>
15
16
16
17
#define PROXY_BIN " mpgen"
@@ -25,12 +26,38 @@ constexpr uint64_t NAME_ANNOTATION_ID = 0xb594888f63f4dbb9ull; // From prox
25
26
constexpr uint64_t SKIP_ANNOTATION_ID = 0x824c08b82695d8ddull ; // From proxy.capnp
26
27
27
28
template <typename Reader>
28
- boost::optional<capnp::schema::Value::Reader> GetAnnotation (const Reader& reader, uint64_t id)
29
+ static bool AnnotationExists (const Reader& reader, uint64_t id)
29
30
{
30
31
for (const auto annotation : reader.getAnnotations ()) {
31
- if (annotation.getId () == id) return annotation.getValue ();
32
+ if (annotation.getId () == id) {
33
+ return true ;
34
+ }
35
+ }
36
+ return false ;
37
+ }
38
+
39
+ template <typename Reader>
40
+ static bool GetAnnotationText (const Reader& reader, uint64_t id, kj::StringPtr* result)
41
+ {
42
+ for (const auto annotation : reader.getAnnotations ()) {
43
+ if (annotation.getId () == id) {
44
+ *result = annotation.getValue ().getText ();
45
+ return true ;
46
+ }
47
+ }
48
+ return false ;
49
+ }
50
+
51
+ template <typename Reader>
52
+ static bool GetAnnotationInt32 (const Reader& reader, uint64_t id, int32_t * result)
53
+ {
54
+ for (const auto annotation : reader.getAnnotations ()) {
55
+ if (annotation.getId () == id) {
56
+ *result = annotation.getValue ().getInt32 ();
57
+ return true ;
58
+ }
32
59
}
33
- return {} ;
60
+ return false ;
34
61
}
35
62
36
63
using CharSlice = kj::ArrayPtr<const char >;
@@ -162,9 +189,7 @@ void Generate(kj::StringPtr src_prefix,
162
189
h << " namespace mp {\n " ;
163
190
164
191
kj::StringPtr message_namespace;
165
- if (auto value = GetAnnotation (file_schema.getProto (), NAMESPACE_ANNOTATION_ID)) {
166
- message_namespace = value->getText ();
167
- }
192
+ GetAnnotationText (file_schema.getProto (), NAMESPACE_ANNOTATION_ID, &message_namespace);
168
193
169
194
std::string base_name = include_base;
170
195
size_t output_slash = base_name.rfind (" /" );
@@ -202,9 +227,7 @@ void Generate(kj::StringPtr src_prefix,
202
227
kj::StringPtr node_name = node_nested.getName ();
203
228
const auto & node = file_schema.getNested (node_name);
204
229
kj::StringPtr proxied_class_type;
205
- if (auto proxy = GetAnnotation (node.getProto (), WRAP_ANNOTATION_ID)) {
206
- proxied_class_type = proxy->getText ();
207
- }
230
+ GetAnnotationText (node.getProto (), WRAP_ANNOTATION_ID, &proxied_class_type);
208
231
209
232
if (node.getProto ().isStruct ()) {
210
233
const auto & struc = node.asStruct ();
@@ -239,7 +262,7 @@ void Generate(kj::StringPtr src_prefix,
239
262
dec << " using Accessors = std::tuple<" ;
240
263
size_t i = 0 ;
241
264
for (const auto field : struc.getFields ()) {
242
- if (GetAnnotation (field.getProto (), SKIP_ANNOTATION_ID)) {
265
+ if (AnnotationExists (field.getProto (), SKIP_ANNOTATION_ID)) {
243
266
continue ;
244
267
}
245
268
if (i) dec << " , " ;
@@ -258,14 +281,12 @@ void Generate(kj::StringPtr src_prefix,
258
281
inl << " using Struct = " << message_namespace << " ::" << node_name << " ;\n " ;
259
282
size_t i = 0 ;
260
283
for (const auto field : struc.getFields ()) {
261
- if (GetAnnotation (field.getProto (), SKIP_ANNOTATION_ID)) {
284
+ if (AnnotationExists (field.getProto (), SKIP_ANNOTATION_ID)) {
262
285
continue ;
263
286
}
264
287
auto field_name = field.getProto ().getName ();
265
288
auto member_name = field_name;
266
- if (auto name = GetAnnotation (field.getProto (), NAME_ANNOTATION_ID)) {
267
- member_name = name->getText ();
268
- }
289
+ GetAnnotationText (field.getProto (), NAME_ANNOTATION_ID, &member_name);
269
290
inl << " static auto get(std::integral_constant<size_t, " << i << " >) -> AUTO_RETURN("
270
291
<< " &" << proxied_class_type << " ::" << member_name << " )\n " ;
271
292
++i;
@@ -300,9 +321,7 @@ void Generate(kj::StringPtr src_prefix,
300
321
for (const auto method : interface.getMethods ()) {
301
322
kj::StringPtr method_name = method.getProto ().getName ();
302
323
kj::StringPtr proxied_method_name = method_name;
303
- if (auto name = GetAnnotation (method.getProto (), NAME_ANNOTATION_ID)) {
304
- proxied_method_name = name->getText ();
305
- }
324
+ GetAnnotationText (method.getProto (), NAME_ANNOTATION_ID, &proxied_method_name);
306
325
307
326
const std::string method_prefix = Format () << message_namespace << " ::" << node_name
308
327
<< " ::" << Cap (method_name);
@@ -311,8 +330,10 @@ void Generate(kj::StringPtr src_prefix,
311
330
312
331
struct Field
313
332
{
314
- boost::optional<::capnp::StructSchema::Field> param;
315
- boost::optional<::capnp::StructSchema::Field> result;
333
+ ::capnp::StructSchema::Field param;
334
+ bool param_is_set = false ;
335
+ ::capnp::StructSchema::Field result;
336
+ bool result_is_set = false ;
316
337
int args = 0 ;
317
338
bool retval = false ;
318
339
bool optional = false ;
@@ -326,7 +347,7 @@ void Generate(kj::StringPtr src_prefix,
326
347
bool has_result = false ;
327
348
328
349
auto add_field = [&](const ::capnp::StructSchema::Field& schema_field, bool param) {
329
- if (GetAnnotation (schema_field.getProto (), SKIP_ANNOTATION_ID)) {
350
+ if (AnnotationExists (schema_field.getProto (), SKIP_ANNOTATION_ID)) {
330
351
return ;
331
352
}
332
353
@@ -336,39 +357,35 @@ void Generate(kj::StringPtr src_prefix,
336
357
fields.emplace_back ();
337
358
}
338
359
auto & field = fields[inserted.first ->second ];
339
- (param ? field.param : field.result ) = schema_field;
360
+ if (param) {
361
+ field.param = schema_field;
362
+ field.param_is_set = true ;
363
+ } else {
364
+ field.result = schema_field;
365
+ field.result_is_set = true ;
366
+ }
340
367
341
368
if (!param && field_name == " result" ) {
342
369
field.retval = true ;
343
370
has_result = true ;
344
371
}
345
372
346
- if (auto value = GetAnnotation (schema_field.getProto (), EXCEPTION_ANNOTATION_ID)) {
347
- field.exception = value->getText ();
348
- }
373
+ GetAnnotationText (schema_field.getProto (), EXCEPTION_ANNOTATION_ID, &field.exception );
349
374
350
- boost::optional<int > count;
351
- if (auto value = GetAnnotation (schema_field.getProto (), COUNT_ANNOTATION_ID)) {
352
- count = value->getInt32 ();
353
- } else if (schema_field.getType ().isStruct ()) {
354
- if (auto value =
355
- GetAnnotation (schema_field.getType ().asStruct ().getProto (), COUNT_ANNOTATION_ID)) {
356
- count = value->getInt32 ();
357
- }
358
- } else if (schema_field.getType ().isInterface ()) {
359
- if (auto value =
360
- GetAnnotation (schema_field.getType ().asInterface ().getProto (), COUNT_ANNOTATION_ID)) {
361
- count = value->getInt32 ();
375
+ int32_t count = 1 ;
376
+ if (!GetAnnotationInt32 (schema_field.getProto (), COUNT_ANNOTATION_ID, &count)) {
377
+ if (schema_field.getType ().isStruct ()) {
378
+ GetAnnotationInt32 (schema_field.getType ().asStruct ().getProto (),
379
+ COUNT_ANNOTATION_ID, &count);
380
+ } else if (schema_field.getType ().isInterface ()) {
381
+ GetAnnotationInt32 (schema_field.getType ().asInterface ().getProto (),
382
+ COUNT_ANNOTATION_ID, &count);
362
383
}
363
384
}
364
385
365
386
366
387
if (inserted.second && !field.retval && !field.exception .size ()) {
367
- if (count) {
368
- field.args = *count;
369
- } else {
370
- field.args = 1 ;
371
- }
388
+ field.args = count;
372
389
}
373
390
};
374
391
@@ -385,7 +402,7 @@ void Generate(kj::StringPtr src_prefix,
385
402
fields[field.second ].optional = true ;
386
403
}
387
404
auto want_field = field_idx.find (" want" + Cap (field.first ));
388
- if (want_field != field_idx.end () && fields[want_field->second ].param ) {
405
+ if (want_field != field_idx.end () && fields[want_field->second ].param_is_set ) {
389
406
fields[want_field->second ].skip = true ;
390
407
fields[field.second ].requested = true ;
391
408
}
@@ -408,12 +425,12 @@ void Generate(kj::StringPtr src_prefix,
408
425
for (const auto & field : fields) {
409
426
if (field.skip ) continue ;
410
427
411
- auto field_name = field.param ? field.param -> getProto (). getName () :
412
- field. result ? field. result -> getProto ().getName () : " " ;
413
- auto field_type = field. param ? field. param -> getType () : field. result -> getType ();
428
+ const auto & f = field.param_is_set ? field.param : field. result ;
429
+ auto field_name = f. getProto ().getName ();
430
+ auto field_type = f. getType ();
414
431
415
432
std::ostringstream field_flags;
416
- field_flags << (!field.param ? " FIELD_OUT" : field.result ? " FIELD_IN | FIELD_OUT" : " FIELD_IN" );
433
+ field_flags << (!field.param_is_set ? " FIELD_OUT" : field.result_is_set ? " FIELD_IN | FIELD_OUT" : " FIELD_IN" );
417
434
if (field.optional ) field_flags << " | FIELD_OPTIONAL" ;
418
435
if (field.requested ) field_flags << " | FIELD_REQUESTED" ;
419
436
if (BoxedType (field_type)) field_flags << " | FIELD_BOXED" ;
0 commit comments