-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathRequestLoader.h
156 lines (120 loc) · 4.45 KB
/
RequestLoader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#ifndef REQUESTLOADER_H
#define REQUESTLOADER_H
#include "GeneratorLoader.h"
#include "graphqlservice/GraphQLParse.h"
#include "graphqlservice/GraphQLService.h"
#include "graphqlservice/internal/Grammar.h"
#include "graphqlservice/internal/Schema.h"
namespace graphql::generator {
using RequestSchemaType = std::shared_ptr<const schema::BaseType>;
using RequestSchemaTypeList = std::vector<RequestSchemaType>;
struct ResponseField;
using ResponseFieldList = std::vector<ResponseField>;
struct ResponseType
{
RequestSchemaType type;
std::string_view cppType;
ResponseFieldList fields;
};
struct ResponseField
{
RequestSchemaType type;
TypeModifierStack modifiers;
std::string_view name;
std::string_view cppName;
std::optional<tao::graphqlpeg::position> position;
ResponseFieldList children;
};
struct RequestVariable
{
RequestSchemaType type;
TypeModifierStack modifiers;
std::string_view name;
std::string_view cppName;
std::string_view defaultValueString;
response::Value defaultValue;
std::optional<tao::graphqlpeg::position> position;
};
using RequestVariableList = std::vector<RequestVariable>;
struct RequestOptions
{
const std::string requestFilename;
const std::string operationName;
const bool noIntrospection = false;
};
class SchemaLoader;
class RequestLoader
{
public:
explicit RequestLoader(RequestOptions&& requestOptions, const SchemaLoader& schemaLoader);
std::string_view getRequestFilename() const noexcept;
std::string_view getOperationDisplayName() const noexcept;
std::string getOperationNamespace() const noexcept;
std::string_view getOperationType() const noexcept;
std::string_view getRequestText() const noexcept;
const ResponseType& getResponseType() const noexcept;
const RequestVariableList& getVariables() const noexcept;
const RequestSchemaTypeList& getReferencedInputTypes() const noexcept;
const RequestSchemaTypeList& getReferencedEnums() const noexcept;
std::string getInputCppType(const RequestSchemaType& wrappedInputType) const noexcept;
static std::string getOutputCppType(
std::string_view outputCppType, const TypeModifierStack& modifiers) noexcept;
static std::pair<RequestSchemaType, TypeModifierStack> unwrapSchemaType(
RequestSchemaType&& type) noexcept;
private:
void buildSchema();
void addTypesToSchema();
RequestSchemaType getSchemaType(
std::string_view type, const TypeModifierStack& modifiers) const noexcept;
void validateRequest() const;
static std::string_view trimWhitespace(std::string_view content) noexcept;
void findOperation();
void collectFragments() noexcept;
void collectVariables() noexcept;
void collectInputTypes(const RequestSchemaType& variableType) noexcept;
void reorderInputTypeDependencies() noexcept;
void collectEnums(const RequestSchemaType& variableType) noexcept;
void collectEnums(const ResponseField& responseField) noexcept;
using FragmentDefinitionMap = std::map<std::string_view, const peg::ast_node*>;
// SelectionVisitor visits the AST and fills in the ResponseType for the request.
class SelectionVisitor
{
public:
explicit SelectionVisitor(const SchemaLoader& schemaLoader,
const FragmentDefinitionMap& fragments, const std::shared_ptr<schema::Schema>& schema,
const RequestSchemaType& type);
void visit(const peg::ast_node& selection);
ResponseFieldList getFields();
private:
void visitField(const peg::ast_node& field);
void visitFragmentSpread(const peg::ast_node& fragmentSpread);
void visitInlineFragment(const peg::ast_node& inlineFragment);
void mergeFragmentFields(ResponseFieldList&& fragmentFields) noexcept;
const SchemaLoader& _schemaLoader;
const FragmentDefinitionMap& _fragments;
const std::shared_ptr<schema::Schema>& _schema;
const RequestSchemaType& _type;
internal::string_view_set _names;
ResponseFieldList _fields;
};
const RequestOptions _requestOptions;
const SchemaLoader& _schemaLoader;
std::shared_ptr<schema::Schema> _schema;
peg::ast _ast;
std::string _requestText;
const peg::ast_node* _operation = nullptr;
std::string_view _operationName;
std::string_view _operationType;
FragmentDefinitionMap _fragments;
ResponseType _responseType;
RequestVariableList _variables;
internal::string_view_set _inputTypeNames;
RequestSchemaTypeList _referencedInputTypes;
internal::string_view_set _enumNames;
RequestSchemaTypeList _referencedEnums;
};
} // namespace graphql::generator
#endif // REQUESTLOADER_H