@@ -28,7 +28,7 @@ namespace service {
28
28
class schema_exception : public std ::exception
29
29
{
30
30
public:
31
- schema_exception (const std::vector<std::string>& messages);
31
+ schema_exception (std::vector<std::string>& & messages);
32
32
33
33
const rapidjson::Document& getErrors () const noexcept ;
34
34
@@ -62,13 +62,14 @@ using FragmentMap = std::unordered_map<std::string, Fragment>;
62
62
// a single field.
63
63
struct ResolverParams
64
64
{
65
+ rapidjson::Document::AllocatorType& allocator;
65
66
const rapidjson::Value::ConstObject& arguments;
66
67
const peg::ast_node* selection;
67
68
const FragmentMap& fragments;
68
69
const rapidjson::Value::ConstObject& variables;
69
70
};
70
71
71
- using Resolver = std::function<rapidjson::Document (ResolverParams&&)>;
72
+ using Resolver = std::function<rapidjson::Value (ResolverParams&&)>;
72
73
using ResolverMap = std::unordered_map<std::string, Resolver>;
73
74
74
75
// Binary data and opaque strings like IDs are encoded in Base64.
@@ -148,14 +149,14 @@ struct ModifiedArgument
148
149
};
149
150
150
151
// Convert a single value to the specified type.
151
- static _Type convert (const rapidjson::Value& value);
152
+ static _Type convert (rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& value);
152
153
153
154
// Call convert on this type without any modifiers.
154
- static _Type require (const std::string& name, const rapidjson::Value::ConstObject& arguments)
155
+ static _Type require (rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments)
155
156
{
156
157
try
157
158
{
158
- return convert (arguments[name.c_str ()]);
159
+ return convert (allocator, arguments[name.c_str ()]);
159
160
}
160
161
catch (const schema_exception& ex)
161
162
{
@@ -167,11 +168,11 @@ struct ModifiedArgument
167
168
}
168
169
169
170
// Wrap require in a try/catch block.
170
- static std::pair<_Type, bool > find (const std::string& name, const rapidjson::Value::ConstObject& arguments) noexcept
171
+ static std::pair<_Type, bool > find (rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments) noexcept
171
172
{
172
173
try
173
174
{
174
- return { require (name, arguments), true };
175
+ return { require (allocator, name, arguments), true };
175
176
}
176
177
catch (const schema_exception&)
177
178
{
@@ -182,16 +183,16 @@ struct ModifiedArgument
182
183
// Peel off the none modifier. If it's included, it should always be last in the list.
183
184
template <TypeModifier _Modifier = TypeModifier::None , TypeModifier... _Other >
184
185
static typename std::enable_if<TypeModifier::None == _Modifier && sizeof ...(_Other) == 0 , _Type>::type require (
185
- const std::string& name, const rapidjson::Value::ConstObject& arguments)
186
+ rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments)
186
187
{
187
188
// Just call through to the non-template method without the modifiers.
188
- return require (name, arguments);
189
+ return require (allocator, name, arguments);
189
190
}
190
191
191
192
// Peel off nullable modifiers.
192
193
template <TypeModifier _Modifier, TypeModifier... _Other>
193
194
static typename std::enable_if<TypeModifier::Nullable == _Modifier, typename ArgumentTraits<_Type, _Modifier, _Other...>::type>::type require (
194
- const std::string& name, const rapidjson::Value::ConstObject& arguments)
195
+ rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments)
195
196
{
196
197
const auto & valueItr = arguments.FindMember (name.c_str ());
197
198
@@ -201,42 +202,42 @@ struct ModifiedArgument
201
202
return nullptr ;
202
203
}
203
204
204
- auto result = require<_Other...>(name, arguments);
205
+ auto result = require<_Other...>(allocator, name, arguments);
205
206
206
207
return std::unique_ptr<decltype (result)> { new decltype (result)(std::move (result)) };
207
208
}
208
209
209
210
// Peel off list modifiers.
210
211
template <TypeModifier _Modifier, TypeModifier... _Other>
211
212
static typename std::enable_if<TypeModifier::List == _Modifier, typename ArgumentTraits<_Type, _Modifier, _Other...>::type>::type require (
212
- const std::string& name, const rapidjson::Value::ConstObject& arguments)
213
+ rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments)
213
214
{
214
215
const auto & values = arguments[name.c_str ()].GetArray ();
215
216
typename ArgumentTraits<_Type, _Modifier, _Other...>::type result (values.Size ());
216
217
217
218
std::transform (values.begin (), values.end (), result.begin (),
218
- [&name](const rapidjson::Value& element)
219
+ [&allocator, & name](const rapidjson::Value& element)
219
220
{
220
- rapidjson::Document single (rapidjson::Type::kObjectType );
221
- auto & allocator = single.GetAllocator ();
222
- rapidjson::Value value;
221
+ rapidjson::Value single (rapidjson::Type::kObjectType );
222
+ rapidjson::Value entry;
223
223
224
- value .CopyFrom (element, allocator);
225
- single.AddMember (rapidjson::StringRef (name.c_str ()), value , allocator);
224
+ entry .CopyFrom (element, allocator);
225
+ single.AddMember (rapidjson::StringRef (name.c_str ()), entry , allocator);
226
226
227
- return require<_Other...>(name.c_str (), const_cast <const rapidjson::Document &>(single).GetObject ());
227
+ return require<_Other...>(allocator, name.c_str (), const_cast <const rapidjson::Value &>(single).GetObject ());
228
228
});
229
229
230
230
return result;
231
231
}
232
232
233
233
// Wrap require with modifiers in a try/catch block.
234
234
template <TypeModifier _Modifier, TypeModifier... _Other>
235
- static std::pair<typename ArgumentTraits<_Type, _Modifier, _Other...>::type, bool > find (const std::string& name, const rapidjson::Value::ConstObject& arguments) noexcept
235
+ static std::pair<typename ArgumentTraits<_Type, _Modifier, _Other...>::type, bool > find (
236
+ rapidjson::Document::AllocatorType& allocator, const std::string& name, const rapidjson::Value::ConstObject& arguments) noexcept
236
237
{
237
238
try
238
239
{
239
- return { require<_Modifier, _Other...>(name, arguments), true };
240
+ return { require<_Modifier, _Other...>(allocator, name, arguments), true };
240
241
}
241
242
catch (const schema_exception&)
242
243
{
@@ -253,7 +254,7 @@ using FloatArgument = ModifiedArgument<double>;
253
254
using StringArgument = ModifiedArgument<std::string>;
254
255
using BooleanArgument = ModifiedArgument<bool >;
255
256
using IdArgument = ModifiedArgument<std::vector<uint8_t >>;
256
- using ScalarArgument = ModifiedArgument<rapidjson::Document >;
257
+ using ScalarArgument = ModifiedArgument<rapidjson::Value >;
257
258
258
259
// Each type should handle fragments with type conditions matching its own
259
260
// name and any inheritted interfaces.
@@ -269,7 +270,7 @@ class Object : public std::enable_shared_from_this<Object>
269
270
explicit Object (TypeNames&& typeNames, ResolverMap&& resolvers);
270
271
virtual ~Object () = default ;
271
272
272
- rapidjson::Document resolve (const peg::ast_node& selection, const FragmentMap& fragments, const rapidjson::Value::ConstObject& variables) const ;
273
+ rapidjson::Value resolve (rapidjson::Document::AllocatorType& allocator, const peg::ast_node& selection, const FragmentMap& fragments, const rapidjson::Value::ConstObject& variables) const ;
273
274
274
275
private:
275
276
TypeNames _typeNames;
@@ -311,13 +312,13 @@ struct ModifiedResult
311
312
};
312
313
313
314
// Convert a single value of the specified type to JSON.
314
- static rapidjson::Document convert (typename std::conditional<std::is_base_of<Object, _Type>::value, std::shared_ptr<Object>, typename ResultTraits<_Type>::type&&>::type result,
315
+ static rapidjson::Value convert (typename std::conditional<std::is_base_of<Object, _Type>::value, std::shared_ptr<Object>, typename ResultTraits<_Type>::type&&>::type result,
315
316
ResolverParams&& params);
316
317
317
318
// Peel off the none modifier. If it's included, it should always be last in the list.
318
319
template <TypeModifier _Modifier = TypeModifier::None, TypeModifier... _Other>
319
320
static typename std::enable_if<TypeModifier::None == _Modifier && sizeof ...(_Other) == 0 && !std::is_same<Object, _Type>::value && std::is_base_of<Object, _Type>::value,
320
- rapidjson::Document >::type convert (typename ResultTraits<_Type>::type&& result, ResolverParams&& params)
321
+ rapidjson::Value >::type convert (typename ResultTraits<_Type>::type&& result, ResolverParams&& params)
321
322
{
322
323
// Call through to the Object specialization with a static_pointer_cast for subclasses of Object.
323
324
static_assert (std::is_same<std::shared_ptr<_Type>, typename ResultTraits<_Type>::type>::value, " this is the derived object type" );
@@ -327,7 +328,7 @@ struct ModifiedResult
327
328
// Peel off the none modifier. If it's included, it should always be last in the list.
328
329
template <TypeModifier _Modifier = TypeModifier::None, TypeModifier... _Other>
329
330
static typename std::enable_if<TypeModifier::None == _Modifier && sizeof ...(_Other) == 0 && (std::is_same<Object, _Type>::value || !std::is_base_of<Object, _Type>::value),
330
- rapidjson::Document >::type convert (typename ResultTraits<_Type>::type&& result, ResolverParams&& params)
331
+ rapidjson::Value >::type convert (typename ResultTraits<_Type>::type&& result, ResolverParams&& params)
331
332
{
332
333
// Just call through to the partial specialization without the modifier.
333
334
return convert (std::move (result), std::move (params));
@@ -336,11 +337,11 @@ struct ModifiedResult
336
337
// Peel off final nullable modifiers for std::shared_ptr of Object and subclasses of Object.
337
338
template <TypeModifier _Modifier, TypeModifier... _Other>
338
339
static typename std::enable_if<TypeModifier::Nullable == _Modifier && std::is_same<std::shared_ptr<_Type>, typename ResultTraits<_Type, _Other...>::type>::value,
339
- rapidjson::Document >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
340
+ rapidjson::Value >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
340
341
{
341
342
if (!result)
342
343
{
343
- return rapidjson::Document (rapidjson::Type::kNullType );
344
+ return rapidjson::Value (rapidjson::Type::kNullType );
344
345
}
345
346
346
347
return convert<_Other...>(std::move (result), std::move (params));
@@ -349,14 +350,14 @@ struct ModifiedResult
349
350
// Peel off nullable modifiers for anything else, which should all be std::unique_ptr.
350
351
template <TypeModifier _Modifier, TypeModifier... _Other>
351
352
static typename std::enable_if<TypeModifier::Nullable == _Modifier && !std::is_same<std::shared_ptr<_Type>, typename ResultTraits<_Type, _Other...>::type>::value,
352
- rapidjson::Document >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
353
+ rapidjson::Value >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
353
354
{
354
355
static_assert (std::is_same<std::unique_ptr<typename ResultTraits<_Type, _Other...>::type>, typename ResultTraits<_Type, _Modifier, _Other...>::type>::value,
355
356
" this is the unique_ptr version" );
356
357
357
358
if (!result)
358
359
{
359
- return rapidjson::Document (rapidjson::Type::kNullType );
360
+ return rapidjson::Value (rapidjson::Type::kNullType );
360
361
}
361
362
362
363
return convert<_Other...>(std::move (*result), std::move (params));
@@ -365,19 +366,15 @@ struct ModifiedResult
365
366
// Peel off list modifiers.
366
367
template <TypeModifier _Modifier, TypeModifier... _Other>
367
368
static typename std::enable_if<TypeModifier::List == _Modifier,
368
- rapidjson::Document >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
369
+ rapidjson::Value >::type convert (typename ResultTraits<_Type, _Modifier, _Other...>::type&& result, ResolverParams&& params)
369
370
{
370
- auto value = rapidjson::Document (rapidjson::Type::kArrayType );
371
- auto & allocator = value.GetAllocator ();
371
+ auto value = rapidjson::Value (rapidjson::Type::kArrayType );
372
372
373
- value.Reserve (result.size (), allocator);
373
+ value.Reserve (result.size (), params. allocator );
374
374
375
375
for (auto & entry : result)
376
376
{
377
- rapidjson::Value element;
378
-
379
- element.CopyFrom (convert<_Other...>(std::move (entry), ResolverParams (params)), allocator);
380
- value.PushBack (element, allocator);
377
+ value.PushBack (convert<_Other...>(std::move (entry), ResolverParams (params)), params.allocator );
381
378
}
382
379
383
380
return value;
@@ -392,7 +389,7 @@ using FloatResult = ModifiedResult<double>;
392
389
using StringResult = ModifiedResult<std::string>;
393
390
using BooleanResult = ModifiedResult<bool >;
394
391
using IdResult = ModifiedResult<std::vector<unsigned char >>;
395
- using ScalarResult = ModifiedResult<rapidjson::Document >;
392
+ using ScalarResult = ModifiedResult<rapidjson::Value >;
396
393
using ObjectResult = ModifiedResult<Object>;
397
394
398
395
// Request scans the fragment definitions and finds the right operation definition to interpret
@@ -410,16 +407,16 @@ class Request : public std::enable_shared_from_this<Request>
410
407
TypeMap _operations;
411
408
};
412
409
413
- // SelectionVisitor visits the AST and resolves a field or fragment, unless its skipped by
410
+ // SelectionVisitor visits the AST and resolves a field or fragment, unless it's skipped by
414
411
// a directive or type condition.
415
412
class SelectionVisitor
416
413
{
417
414
public:
418
- SelectionVisitor (const FragmentMap& fragments, const rapidjson::Document::ConstObject& variables, const TypeNames& typeNames, const ResolverMap& resolvers);
415
+ SelectionVisitor (rapidjson::Document::AllocatorType& allocator, const FragmentMap& fragments, const rapidjson::Document::ConstObject& variables, const TypeNames& typeNames, const ResolverMap& resolvers);
419
416
420
417
void visit (const peg::ast_node& selection);
421
418
422
- rapidjson::Document getValues ();
419
+ rapidjson::Value getValues ();
423
420
424
421
private:
425
422
bool shouldSkip (const std::vector<std::unique_ptr<peg::ast_node>>* directives) const ;
@@ -428,23 +425,25 @@ class SelectionVisitor
428
425
void visitFragmentSpread (const peg::ast_node& fragmentSpread);
429
426
void visitInlineFragment (const peg::ast_node& inlineFragment);
430
427
428
+ rapidjson::Document::AllocatorType& _allocator;
431
429
const FragmentMap& _fragments;
432
430
const rapidjson::Document::ConstObject& _variables;
433
431
const TypeNames& _typeNames;
434
432
const ResolverMap& _resolvers;
435
- rapidjson::Document _values;
433
+
434
+ rapidjson::Value _values;
436
435
};
437
436
438
437
// ValueVisitor visits the AST and builds a JSON representation of any value
439
438
// hardcoded or referencing a variable in an operation.
440
439
class ValueVisitor
441
440
{
442
441
public:
443
- ValueVisitor (const rapidjson::Document::ConstObject& variables);
442
+ ValueVisitor (rapidjson::Document::AllocatorType& allocator, const rapidjson::Document::ConstObject& variables);
444
443
445
444
void visit (const peg::ast_node& value);
446
445
447
- rapidjson::Document getValue ();
446
+ rapidjson::Value getValue ();
448
447
449
448
private:
450
449
void visitVariable (const peg::ast_node& variable);
@@ -457,8 +456,9 @@ class ValueVisitor
457
456
void visitListValue (const peg::ast_node& listValue);
458
457
void visitObjectValue (const peg::ast_node& objectValue);
459
458
459
+ rapidjson::Document::AllocatorType& _allocator;
460
460
const rapidjson::Document::ConstObject& _variables;
461
- rapidjson::Document _value;
461
+ rapidjson::Value _value;
462
462
};
463
463
464
464
// FragmentDefinitionVisitor visits the AST and collects all of the fragment
0 commit comments