Skip to content

Commit 3eb7768

Browse files
committed
Refactor GraphQLService.cpp visitors into RequestLoader.*
1 parent bd4c980 commit 3eb7768

File tree

4 files changed

+1077
-1042
lines changed

4 files changed

+1077
-1042
lines changed

include/RequestLoader.h

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#ifndef REQUESTLOADER_H
7+
#define REQUESTLOADER_H
8+
9+
#include "graphqlservice/GraphQLParse.h"
10+
#include "graphqlservice/GraphQLService.h"
11+
12+
namespace graphql::runtime {
13+
14+
// ValueVisitor visits the AST and builds a response::Value representation of any value
15+
// hardcoded or referencing a variable in an operation.
16+
class ValueVisitor
17+
{
18+
public:
19+
ValueVisitor(const response::Value& variables);
20+
21+
void visit(const peg::ast_node& value);
22+
23+
response::Value getValue();
24+
25+
private:
26+
void visitVariable(const peg::ast_node& variable);
27+
void visitIntValue(const peg::ast_node& intValue);
28+
void visitFloatValue(const peg::ast_node& floatValue);
29+
void visitStringValue(const peg::ast_node& stringValue);
30+
void visitBooleanValue(const peg::ast_node& booleanValue);
31+
void visitNullValue(const peg::ast_node& nullValue);
32+
void visitEnumValue(const peg::ast_node& enumValue);
33+
void visitListValue(const peg::ast_node& listValue);
34+
void visitObjectValue(const peg::ast_node& objectValue);
35+
36+
const response::Value& _variables;
37+
response::Value _value;
38+
};
39+
40+
// DirectiveVisitor visits the AST and builds a 2-level map of directive names to argument
41+
// name/value pairs.
42+
class DirectiveVisitor
43+
{
44+
public:
45+
explicit DirectiveVisitor(const response::Value& variables);
46+
47+
void visit(const peg::ast_node& directives);
48+
49+
bool shouldSkip() const;
50+
response::Value getDirectives();
51+
52+
private:
53+
const response::Value& _variables;
54+
55+
response::Value _directives;
56+
};
57+
58+
// As we recursively expand fragment spreads and inline fragments, we want to accumulate the
59+
// directives at each location and merge them with any directives included in outer fragments to
60+
// build the complete set of directives for nested fragments. Directives with the same name at the
61+
// same location will be overwritten by the innermost fragment.
62+
struct FragmentDirectives
63+
{
64+
response::Value fragmentDefinitionDirectives;
65+
response::Value fragmentSpreadDirectives;
66+
response::Value inlineFragmentDirectives;
67+
};
68+
69+
// SelectionVisitor visits the AST and resolves a field or fragment, unless it's skipped by
70+
// a directive or type condition.
71+
class SelectionVisitor
72+
{
73+
public:
74+
explicit SelectionVisitor(const service::SelectionSetParams& selectionSetParams,
75+
const service::FragmentMap& fragments, const response::Value& variables,
76+
const service::TypeNames& typeNames, const service::ResolverMap& resolvers, size_t count);
77+
78+
void visit(const peg::ast_node& selection);
79+
80+
std::vector<std::pair<std::string_view, std::future<service::ResolverResult>>> getValues();
81+
82+
private:
83+
void visitField(const peg::ast_node& field);
84+
void visitFragmentSpread(const peg::ast_node& fragmentSpread);
85+
void visitInlineFragment(const peg::ast_node& inlineFragment);
86+
87+
const service::ResolverContext _resolverContext;
88+
const std::shared_ptr<service::RequestState>& _state;
89+
const response::Value& _operationDirectives;
90+
const std::optional<std::reference_wrapper<const service::field_path>> _path;
91+
const std::launch _launch;
92+
const service::FragmentMap& _fragments;
93+
const response::Value& _variables;
94+
const service::TypeNames& _typeNames;
95+
const service::ResolverMap& _resolvers;
96+
97+
std::list<FragmentDirectives> _fragmentDirectives;
98+
internal::string_view_set _names;
99+
std::vector<std::pair<std::string_view, std::future<service::ResolverResult>>> _values;
100+
};
101+
102+
// FragmentDefinitionVisitor visits the AST and collects all of the fragment
103+
// definitions in the document.
104+
class FragmentDefinitionVisitor
105+
{
106+
public:
107+
FragmentDefinitionVisitor(const response::Value& variables);
108+
109+
service::FragmentMap getFragments();
110+
111+
void visit(const peg::ast_node& fragmentDefinition);
112+
113+
private:
114+
const response::Value& _variables;
115+
116+
service::FragmentMap _fragments;
117+
};
118+
119+
// OperationDefinitionVisitor visits the AST and executes the one with the specified
120+
// operation name.
121+
class OperationDefinitionVisitor
122+
{
123+
public:
124+
OperationDefinitionVisitor(service::ResolverContext resolverContext, std::launch launch,
125+
std::shared_ptr<service::RequestState> state, const service::TypeMap& operations, response::Value&& variables,
126+
service::FragmentMap&& fragments);
127+
128+
std::future<service::ResolverResult> getValue();
129+
130+
void visit(std::string_view operationType, const peg::ast_node& operationDefinition);
131+
132+
private:
133+
const service::ResolverContext _resolverContext;
134+
const std::launch _launch;
135+
std::shared_ptr<service::OperationData> _params;
136+
const service::TypeMap& _operations;
137+
std::future<service::ResolverResult> _result;
138+
};
139+
140+
// SubscriptionDefinitionVisitor visits the AST collects the fields referenced in the subscription
141+
// at the point where we create a subscription.
142+
class SubscriptionDefinitionVisitor
143+
{
144+
public:
145+
SubscriptionDefinitionVisitor(service::SubscriptionParams&& params, service::SubscriptionCallback&& callback,
146+
service::FragmentMap&& fragments, const std::shared_ptr<service::Object>& subscriptionObject);
147+
148+
const peg::ast_node& getRoot() const;
149+
std::shared_ptr<service::SubscriptionData> getRegistration();
150+
151+
void visit(const peg::ast_node& operationDefinition);
152+
153+
private:
154+
void visitField(const peg::ast_node& field);
155+
void visitFragmentSpread(const peg::ast_node& fragmentSpread);
156+
void visitInlineFragment(const peg::ast_node& inlineFragment);
157+
158+
service::SubscriptionParams _params;
159+
service::SubscriptionCallback _callback;
160+
service::FragmentMap _fragments;
161+
const std::shared_ptr<service::Object>& _subscriptionObject;
162+
service::SubscriptionName _field;
163+
response::Value _arguments;
164+
response::Value _fieldDirectives;
165+
std::shared_ptr<service::SubscriptionData> _result;
166+
};
167+
168+
} /* namespace graphql::runtime */
169+
170+
#endif // REQUESTLOADER_H

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ endif()
285285
add_library(graphqlservice
286286
GraphQLService.cpp
287287
GraphQLSchema.cpp
288+
RequestLoader.cpp
288289
Validation.cpp)
289290
add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice)
290291
target_link_libraries(graphqlservice PUBLIC

0 commit comments

Comments
 (0)