redsnow 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/ext/snowcrash/bin/snowcrash +0 -0
- data/ext/snowcrash/snowcrash.xcworkspace/contents.xcworkspacedata +10 -0
- data/ext/snowcrash/src/ActionParser.h +35 -33
- data/ext/snowcrash/src/AssetParser.h +17 -17
- data/ext/snowcrash/src/Blueprint.h +101 -66
- data/ext/snowcrash/src/BlueprintParser.h +219 -10
- data/ext/snowcrash/src/BlueprintSourcemap.h +1 -1
- data/ext/snowcrash/src/BlueprintUtility.h +14 -14
- data/ext/snowcrash/src/CBlueprint.cc +29 -10
- data/ext/snowcrash/src/CBlueprint.h +19 -3
- data/ext/snowcrash/src/CBlueprintSourcemap.cc +20 -10
- data/ext/snowcrash/src/CBlueprintSourcemap.h +12 -3
- data/ext/snowcrash/src/CodeBlockUtility.h +25 -25
- data/ext/snowcrash/src/HTTP.cc +3 -0
- data/ext/snowcrash/src/HTTP.h +9 -6
- data/ext/snowcrash/src/HeadersParser.h +34 -14
- data/ext/snowcrash/src/ParameterParser.h +21 -21
- data/ext/snowcrash/src/ParametersParser.h +6 -5
- data/ext/snowcrash/src/PayloadParser.h +174 -129
- data/ext/snowcrash/src/RegexMatch.h +3 -3
- data/ext/snowcrash/src/ResourceGroupParser.h +5 -4
- data/ext/snowcrash/src/ResourceParser.h +30 -26
- data/ext/snowcrash/src/Section.cc +6 -6
- data/ext/snowcrash/src/Section.h +2 -2
- data/ext/snowcrash/src/SectionParser.h +41 -41
- data/ext/snowcrash/src/SectionParserData.h +10 -10
- data/ext/snowcrash/src/SectionProcessor.h +70 -30
- data/ext/snowcrash/src/Serialize.h +3 -3
- data/ext/snowcrash/src/SerializeJSON.cc +124 -96
- data/ext/snowcrash/src/SerializeJSON.h +1 -1
- data/ext/snowcrash/src/SerializeYAML.cc +71 -53
- data/ext/snowcrash/src/SerializeYAML.h +1 -1
- data/ext/snowcrash/src/Signature.cc +2 -2
- data/ext/snowcrash/src/Signature.h +1 -1
- data/ext/snowcrash/src/SourceAnnotation.h +23 -23
- data/ext/snowcrash/src/StringUtility.h +71 -9
- data/ext/snowcrash/src/SymbolTable.h +17 -17
- data/ext/snowcrash/src/UriTemplateParser.cc +5 -5
- data/ext/snowcrash/src/UriTemplateParser.h +9 -9
- data/ext/snowcrash/src/ValuesParser.h +2 -2
- data/ext/snowcrash/src/Version.h +1 -1
- data/ext/snowcrash/src/csnowcrash.cc +10 -8
- data/ext/snowcrash/src/snowcrash.cc +9 -9
- data/ext/snowcrash/src/snowcrash.h +6 -8
- data/ext/snowcrash/src/snowcrash/snowcrash.cc +14 -14
- data/ext/snowcrash/src/win/RegexMatch.cc +7 -7
- data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
- data/ext/snowcrash/tools/homebrew/snowcrash.rb +1 -1
- data/lib/redsnow/binding.rb +8 -2
- data/lib/redsnow/blueprint.rb +4 -3
- data/lib/redsnow/sourcemap.rb +6 -4
- data/lib/redsnow/version.rb +1 -1
- metadata +4 -17
@@ -39,13 +39,13 @@ namespace snowcrash {
|
|
39
39
|
|
40
40
|
/** Additonal Parameter Traits Type matching regex */
|
41
41
|
const char* const AdditionalTraitsTypeRegex = CSV_LEADINOUT "([^,]*)" CSV_LEADINOUT;
|
42
|
-
|
42
|
+
|
43
43
|
/** Parameter Values matching regex */
|
44
44
|
const char* const ParameterValuesRegex = "^[[:blank:]]*[Vv]alues[[:blank:]]*$";
|
45
45
|
|
46
46
|
/** Values expected content */
|
47
47
|
const char* const ExpectedValuesContent = "nested list of possible parameter values, one element per list item e.g. '`value`'";
|
48
|
-
|
48
|
+
|
49
49
|
/** Parameter description delimiter */
|
50
50
|
const std::string DescriptionIdentifier = "...";
|
51
51
|
|
@@ -59,7 +59,7 @@ namespace snowcrash {
|
|
59
59
|
const MarkdownNodes& siblings,
|
60
60
|
SectionParserData& pd,
|
61
61
|
SectionLayout& layout,
|
62
|
-
|
62
|
+
const ParseResultRef<Parameter>& out) {
|
63
63
|
|
64
64
|
mdp::ByteBuffer signature, remainingContent;
|
65
65
|
signature = GetFirstLine(node->text, remainingContent);
|
@@ -81,7 +81,7 @@ namespace snowcrash {
|
|
81
81
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
82
82
|
const MarkdownNodes& siblings,
|
83
83
|
SectionParserData& pd,
|
84
|
-
|
84
|
+
const ParseResultRef<Parameter>& out) {
|
85
85
|
|
86
86
|
if (pd.sectionContext() != ValuesSectionType) {
|
87
87
|
return node;
|
@@ -107,7 +107,7 @@ namespace snowcrash {
|
|
107
107
|
out.sourceMap.values.collection.clear();
|
108
108
|
}
|
109
109
|
|
110
|
-
|
110
|
+
ParseResultRef<Values> values(out.report, out.node.values, out.sourceMap.values);
|
111
111
|
ValuesParser::parse(node, siblings, pd, values);
|
112
112
|
|
113
113
|
if (out.node.values.empty()) {
|
@@ -163,7 +163,7 @@ namespace snowcrash {
|
|
163
163
|
static void parseSignature(const mdp::MarkdownNodeIterator& node,
|
164
164
|
SectionParserData& pd,
|
165
165
|
mdp::ByteBuffer& signature,
|
166
|
-
|
166
|
+
const ParseResultRef<Parameter>& out) {
|
167
167
|
|
168
168
|
out.node.use = UndefinedParameterUse;
|
169
169
|
|
@@ -172,10 +172,10 @@ namespace snowcrash {
|
|
172
172
|
CaptureGroups captureGroups;
|
173
173
|
|
174
174
|
if (isValidParameterSignature(signature)) {
|
175
|
-
|
175
|
+
|
176
176
|
mdp::ByteBuffer innerSignature = signature;
|
177
177
|
innerSignature = TrimString(innerSignature);
|
178
|
-
|
178
|
+
|
179
179
|
size_t firstSpace = innerSignature.find(" ");
|
180
180
|
|
181
181
|
if (firstSpace == std::string::npos) {
|
@@ -196,7 +196,7 @@ namespace snowcrash {
|
|
196
196
|
innerSignature = innerSignature.substr(0, descriptionPos);
|
197
197
|
innerSignature = TrimString(innerSignature);
|
198
198
|
}
|
199
|
-
|
199
|
+
|
200
200
|
size_t attributesPos = innerSignature.find("(");
|
201
201
|
|
202
202
|
if (attributesPos != std::string::npos) {
|
@@ -212,7 +212,7 @@ namespace snowcrash {
|
|
212
212
|
innerSignature = TrimString(innerSignature);
|
213
213
|
}
|
214
214
|
}
|
215
|
-
|
215
|
+
|
216
216
|
if (innerSignature.length() > 0) {
|
217
217
|
// Remove =
|
218
218
|
out.node.defaultValue = innerSignature;
|
@@ -264,7 +264,7 @@ namespace snowcrash {
|
|
264
264
|
static void parseAdditionalTraits(const mdp::MarkdownNodeIterator& node,
|
265
265
|
SectionParserData& pd,
|
266
266
|
mdp::ByteBuffer& traits,
|
267
|
-
|
267
|
+
const ParseResultRef<Parameter>& out) {
|
268
268
|
|
269
269
|
TrimString(traits);
|
270
270
|
|
@@ -351,7 +351,7 @@ namespace snowcrash {
|
|
351
351
|
|
352
352
|
static void checkExampleAndDefaultValue(const mdp::MarkdownNodeIterator& node,
|
353
353
|
SectionParserData& pd,
|
354
|
-
|
354
|
+
const ParseResultRef<Parameter>& out) {
|
355
355
|
|
356
356
|
bool isExampleFound = false;
|
357
357
|
bool isDefaultFound = false;
|
@@ -395,23 +395,23 @@ namespace snowcrash {
|
|
395
395
|
sourceMap));
|
396
396
|
}
|
397
397
|
}
|
398
|
-
|
398
|
+
|
399
399
|
/** Determine if a signature is a valid parameter*/
|
400
400
|
static bool isValidParameterSignature(const mdp::ByteBuffer& signature) {
|
401
|
-
|
401
|
+
|
402
402
|
mdp::ByteBuffer innerSignature = signature;
|
403
403
|
innerSignature = TrimString(innerSignature);
|
404
|
-
|
404
|
+
|
405
405
|
if (innerSignature.length() == 0) {
|
406
406
|
return false; // Empty string, invalid
|
407
407
|
}
|
408
|
-
|
408
|
+
|
409
409
|
size_t firstSpace = innerSignature.find(" ");
|
410
410
|
|
411
411
|
if (firstSpace == std::string::npos) {
|
412
412
|
return RegexMatch(innerSignature, "^" PARAMETER_IDENTIFIER "$");
|
413
413
|
}
|
414
|
-
|
414
|
+
|
415
415
|
std::string paramName = innerSignature.substr(0, firstSpace);
|
416
416
|
|
417
417
|
if (!RegexMatch(paramName, "^" PARAMETER_IDENTIFIER "$")) {
|
@@ -427,7 +427,7 @@ namespace snowcrash {
|
|
427
427
|
innerSignature = innerSignature.substr(0, descriptionPos);
|
428
428
|
innerSignature = TrimString(innerSignature);
|
429
429
|
}
|
430
|
-
|
430
|
+
|
431
431
|
size_t attributesPos = innerSignature.find("(");
|
432
432
|
|
433
433
|
if (attributesPos != std::string::npos) {
|
@@ -441,11 +441,11 @@ namespace snowcrash {
|
|
441
441
|
innerSignature = innerSignature.substr(0, attributesPos);
|
442
442
|
innerSignature = TrimString(innerSignature);
|
443
443
|
}
|
444
|
-
|
444
|
+
|
445
445
|
if (innerSignature.length() == 0) {
|
446
446
|
return true;
|
447
447
|
}
|
448
|
-
|
448
|
+
|
449
449
|
if (innerSignature.substr(0,1) == "=") {
|
450
450
|
innerSignature = innerSignature.substr(1);
|
451
451
|
innerSignature = TrimString(innerSignature);
|
@@ -458,7 +458,7 @@ namespace snowcrash {
|
|
458
458
|
return true;
|
459
459
|
}
|
460
460
|
}
|
461
|
-
|
461
|
+
|
462
462
|
return false;
|
463
463
|
}
|
464
464
|
|
@@ -36,7 +36,7 @@ namespace snowcrash {
|
|
36
36
|
const MarkdownNodes& siblings,
|
37
37
|
SectionParserData& pd,
|
38
38
|
SectionLayout& layout,
|
39
|
-
|
39
|
+
const ParseResultRef<Parameters>& out) {
|
40
40
|
|
41
41
|
mdp::ByteBuffer remainingContent;
|
42
42
|
|
@@ -61,7 +61,7 @@ namespace snowcrash {
|
|
61
61
|
static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
|
62
62
|
const MarkdownNodes& siblings,
|
63
63
|
SectionParserData& pd,
|
64
|
-
|
64
|
+
const ParseResultRef<Parameters>& out) {
|
65
65
|
|
66
66
|
return node;
|
67
67
|
}
|
@@ -69,13 +69,14 @@ namespace snowcrash {
|
|
69
69
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
70
70
|
const MarkdownNodes& siblings,
|
71
71
|
SectionParserData& pd,
|
72
|
-
|
72
|
+
const ParseResultRef<Parameters>& out) {
|
73
73
|
|
74
74
|
if (pd.sectionContext() != ParameterSectionType) {
|
75
75
|
return node;
|
76
76
|
}
|
77
77
|
|
78
|
-
|
78
|
+
IntermediateParseResult<Parameter> parameter(out.report);
|
79
|
+
|
79
80
|
ParameterParser::parse(node, siblings, pd, parameter);
|
80
81
|
|
81
82
|
if (!out.node.empty()) {
|
@@ -146,7 +147,7 @@ namespace snowcrash {
|
|
146
147
|
|
147
148
|
static void finalize(const MarkdownNodeIterator& node,
|
148
149
|
SectionParserData& pd,
|
149
|
-
|
150
|
+
const ParseResultRef<Parameters>& out) {
|
150
151
|
|
151
152
|
if (out.node.empty()) {
|
152
153
|
|
@@ -52,7 +52,7 @@ namespace snowcrash {
|
|
52
52
|
const MarkdownNodes& siblings,
|
53
53
|
SectionParserData& pd,
|
54
54
|
SectionLayout& layout,
|
55
|
-
|
55
|
+
const ParseResultRef<Payload>& out) {
|
56
56
|
|
57
57
|
mdp::ByteBuffer signature, remainingContent;
|
58
58
|
signature = GetFirstLine(node->text, remainingContent);
|
@@ -97,16 +97,16 @@ namespace snowcrash {
|
|
97
97
|
static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
|
98
98
|
const MarkdownNodes& siblings,
|
99
99
|
SectionParserData& pd,
|
100
|
-
|
100
|
+
const ParseResultRef<Payload>& out) {
|
101
101
|
|
102
102
|
mdp::ByteBuffer content;
|
103
103
|
|
104
|
-
if (!out.node.
|
104
|
+
if (!out.node.reference.id.empty()) {
|
105
105
|
//WARN: ignoring extraneous content after symbol reference
|
106
106
|
std::stringstream ss;
|
107
107
|
|
108
108
|
ss << "ignoring extraneous content after symbol reference";
|
109
|
-
ss << ", expected symbol reference only e.g. '[" << out.node.
|
109
|
+
ss << ", expected symbol reference only e.g. '[" << out.node.reference.id << "][]'";
|
110
110
|
|
111
111
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
112
112
|
out.report.warnings.push_back(Warning(ss.str(),
|
@@ -138,12 +138,12 @@ namespace snowcrash {
|
|
138
138
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
139
139
|
const MarkdownNodes& siblings,
|
140
140
|
SectionParserData& pd,
|
141
|
-
|
141
|
+
const ParseResultRef<Payload>& out) {
|
142
142
|
|
143
143
|
switch (pd.sectionContext()) {
|
144
144
|
case HeadersSectionType:
|
145
145
|
{
|
146
|
-
|
146
|
+
ParseResultRef<Headers> headers(out.report, out.node.headers, out.sourceMap.headers);
|
147
147
|
return HeadersParser::parse(node, siblings, pd, headers);
|
148
148
|
}
|
149
149
|
|
@@ -157,7 +157,7 @@ namespace snowcrash {
|
|
157
157
|
sourceMap));
|
158
158
|
}
|
159
159
|
|
160
|
-
|
160
|
+
ParseResultRef<Asset> asset(out.report, out.node.body, out.sourceMap.body);
|
161
161
|
return AssetParser::parse(node, siblings, pd, asset);
|
162
162
|
}
|
163
163
|
|
@@ -171,7 +171,7 @@ namespace snowcrash {
|
|
171
171
|
sourceMap));
|
172
172
|
}
|
173
173
|
|
174
|
-
|
174
|
+
ParseResultRef<Asset> asset(out.report, out.node.schema, out.sourceMap.schema);
|
175
175
|
return AssetParser::parse(node, siblings, pd, asset);
|
176
176
|
}
|
177
177
|
|
@@ -186,7 +186,7 @@ namespace snowcrash {
|
|
186
186
|
const MarkdownNodes& siblings,
|
187
187
|
SectionParserData& pd,
|
188
188
|
SectionType& sectionType,
|
189
|
-
|
189
|
+
const ParseResultRef<Payload>& out) {
|
190
190
|
|
191
191
|
if ((node->type == mdp::ParagraphMarkdownNodeType ||
|
192
192
|
node->type == mdp::CodeMarkdownNodeType) &&
|
@@ -200,7 +200,7 @@ namespace snowcrash {
|
|
200
200
|
|
201
201
|
return ++MarkdownNodeIterator(node);
|
202
202
|
}
|
203
|
-
|
203
|
+
|
204
204
|
return SectionProcessorBase<Payload>::processUnexpectedNode(node, siblings, pd, sectionType, out);
|
205
205
|
}
|
206
206
|
|
@@ -296,73 +296,16 @@ namespace snowcrash {
|
|
296
296
|
|
297
297
|
static void finalize(const MarkdownNodeIterator& node,
|
298
298
|
SectionParserData& pd,
|
299
|
-
|
300
|
-
|
301
|
-
bool warnEmptyBody = false;
|
302
|
-
|
303
|
-
mdp::ByteBuffer contentLength;
|
304
|
-
mdp::ByteBuffer transferEncoding;
|
299
|
+
const ParseResultRef<Payload>& out) {
|
305
300
|
|
306
301
|
SectionType sectionType = pd.sectionContext();
|
307
302
|
|
308
|
-
|
309
|
-
it != out.node.headers.end();
|
310
|
-
++it) {
|
303
|
+
if (sectionType == RequestSectionType || sectionType == RequestBodySectionType) {
|
311
304
|
|
312
|
-
|
313
|
-
|
314
|
-
}
|
305
|
+
checkRequest(node, pd, out);
|
306
|
+
} else if (sectionType == ResponseSectionType || sectionType == ResponseBodySectionType) {
|
315
307
|
|
316
|
-
|
317
|
-
transferEncoding = it->second;
|
318
|
-
}
|
319
|
-
}
|
320
|
-
|
321
|
-
if ((sectionType == RequestSectionType || sectionType == RequestBodySectionType) && out.node.body.empty()) {
|
322
|
-
|
323
|
-
// Warn when content-length or transfer-encoding is specified or both headers and body are empty
|
324
|
-
if (out.node.headers.empty()) {
|
325
|
-
warnEmptyBody = true;
|
326
|
-
} else {
|
327
|
-
warnEmptyBody = !contentLength.empty() || !transferEncoding.empty();
|
328
|
-
}
|
329
|
-
|
330
|
-
if (warnEmptyBody) {
|
331
|
-
// WARN: empty body
|
332
|
-
std::stringstream ss;
|
333
|
-
ss << "empty " << SectionName(sectionType) << " " << SectionName(BodySectionType);
|
334
|
-
|
335
|
-
if (!contentLength.empty()) {
|
336
|
-
ss << ", expected " << SectionName(BodySectionType) << " for '" << contentLength << "' Content-Length";
|
337
|
-
} else if (!transferEncoding.empty()) {
|
338
|
-
ss << ", expected " << SectionName(BodySectionType) << " for '" << transferEncoding << "' Transfer-Encoding";
|
339
|
-
}
|
340
|
-
|
341
|
-
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
342
|
-
out.report.warnings.push_back(Warning(ss.str(),
|
343
|
-
EmptyDefinitionWarning,
|
344
|
-
sourceMap));
|
345
|
-
}
|
346
|
-
} else if ((sectionType == ResponseSectionType || sectionType == ResponseBodySectionType)) {
|
347
|
-
|
348
|
-
HTTPStatusCode code = 200;
|
349
|
-
|
350
|
-
if (!out.node.name.empty()) {
|
351
|
-
std::stringstream(out.node.name) >> code;
|
352
|
-
}
|
353
|
-
|
354
|
-
StatusCodeTraits statusCodeTraits = GetStatusCodeTrait(code);
|
355
|
-
|
356
|
-
if (!statusCodeTraits.allowBody && !out.node.body.empty()) {
|
357
|
-
// WARN: not empty body
|
358
|
-
std::stringstream ss;
|
359
|
-
ss << "the " << code << " response MUST NOT include a " << SectionName(BodySectionType);
|
360
|
-
|
361
|
-
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
362
|
-
out.report.warnings.push_back(Warning(ss.str(),
|
363
|
-
EmptyDefinitionWarning,
|
364
|
-
sourceMap));
|
365
|
-
}
|
308
|
+
checkResponse(node, pd, out);
|
366
309
|
}
|
367
310
|
}
|
368
311
|
|
@@ -421,7 +364,7 @@ namespace snowcrash {
|
|
421
364
|
static bool parseSignature(const MarkdownNodeIterator& node,
|
422
365
|
SectionParserData& pd,
|
423
366
|
const mdp::ByteBuffer& signature,
|
424
|
-
|
367
|
+
const ParseResultRef<Payload>& out) {
|
425
368
|
|
426
369
|
const char* regex;
|
427
370
|
mdp::ByteBuffer mediaType;
|
@@ -524,93 +467,195 @@ namespace snowcrash {
|
|
524
467
|
return true;
|
525
468
|
}
|
526
469
|
|
470
|
+
/** Given the reference id(name), initializes reference of the payload accordingly(if possible resolve it) */
|
527
471
|
static bool parseSymbolReference(const MarkdownNodeIterator& node,
|
528
472
|
SectionParserData& pd,
|
529
473
|
mdp::ByteBuffer& source,
|
530
|
-
|
474
|
+
const ParseResultRef<Payload>& out) {
|
531
475
|
|
532
|
-
|
533
|
-
ResourceModel model;
|
534
|
-
SourceMap<ResourceModel> modelSM;
|
476
|
+
Identifier symbol;
|
535
477
|
|
536
478
|
TrimString(source);
|
537
479
|
|
538
480
|
if (GetSymbolReference(source, symbol)) {
|
539
|
-
|
481
|
+
|
482
|
+
out.node.reference.id = symbol;
|
483
|
+
out.node.reference.meta.node = node;
|
484
|
+
out.node.reference.type = Reference::SymbolReference;
|
540
485
|
|
541
486
|
if (pd.exportSourceMap() && !symbol.empty()) {
|
542
|
-
out.sourceMap.
|
487
|
+
out.sourceMap.reference.sourceMap = node->sourceMap;
|
543
488
|
}
|
544
489
|
|
545
|
-
// If symbol
|
490
|
+
// If symbol has not been defined yet in symbol table
|
546
491
|
if (pd.symbolTable.resourceModels.find(symbol) == pd.symbolTable.resourceModels.end()) {
|
547
492
|
|
548
|
-
|
549
|
-
std::stringstream ss;
|
550
|
-
ss << "Undefined symbol " << symbol;
|
551
|
-
|
552
|
-
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
553
|
-
out.report.error = Error(ss.str(), SymbolError, sourceMap);
|
493
|
+
out.node.reference.meta.state = Reference::StatePending;
|
554
494
|
|
555
495
|
return true;
|
556
496
|
}
|
557
497
|
|
558
|
-
|
559
|
-
|
560
|
-
out
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
498
|
+
out.node.reference.meta.state = Reference::StateResolved;
|
499
|
+
|
500
|
+
assingReferredPayload(pd, out);
|
501
|
+
|
502
|
+
return true;
|
503
|
+
}
|
504
|
+
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
|
508
|
+
/**
|
509
|
+
* \brief Assigns the reference, referred as reference id(name), into the payload
|
510
|
+
* \param pd Section parser state
|
511
|
+
* \param out Processed output
|
512
|
+
*/
|
513
|
+
static void assingReferredPayload(SectionParserData& pd,
|
514
|
+
const ParseResultRef<Payload>& out) {
|
515
|
+
|
516
|
+
SourceMap<ResourceModel> modelSM;
|
517
|
+
ResourceModel model = pd.symbolTable.resourceModels.at(out.node.reference.id);
|
518
|
+
|
519
|
+
|
520
|
+
out.node.description = model.description;
|
521
|
+
out.node.parameters = model.parameters;
|
522
|
+
|
523
|
+
HeaderIterator modelContentTypeIt = std::find_if(model.headers.begin(),
|
524
|
+
model.headers.end(),
|
525
|
+
std::bind2nd(MatchFirstWith<Header, std::string>(),
|
526
|
+
HTTPHeaderName::ContentType));
|
527
|
+
|
528
|
+
bool isPayloadContentType = !out.node.headers.empty();
|
529
|
+
bool isModelContentType = modelContentTypeIt != model.headers.end();
|
530
|
+
|
531
|
+
if (isPayloadContentType && isModelContentType) {
|
532
|
+
|
533
|
+
// WARN: Ignoring payload content-type, when referencing a model with headers
|
534
|
+
std::stringstream ss;
|
535
|
+
|
536
|
+
ss << "ignoring additional " << SectionName(pd.sectionContext()) << " header(s), ";
|
537
|
+
ss << "specify this header(s) in the referenced model definition instead";
|
538
|
+
|
539
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(out.node.reference.meta.node->sourceMap, pd.sourceData);
|
540
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
541
|
+
IgnoringWarning,
|
542
|
+
sourceMap));
|
543
|
+
}
|
544
|
+
|
545
|
+
if (isPayloadContentType && !isModelContentType) {
|
546
|
+
out.node.headers.insert(out.node.headers.end(), model.headers.begin(), model.headers.end());
|
547
|
+
} else {
|
548
|
+
out.node.headers = model.headers;
|
549
|
+
}
|
550
|
+
|
551
|
+
out.node.body = model.body;
|
552
|
+
out.node.schema = model.schema;
|
553
|
+
|
554
|
+
if (pd.exportSourceMap()) {
|
555
|
+
|
556
|
+
modelSM = pd.symbolSourceMapTable.resourceModels.at(out.node.reference.id);
|
557
|
+
|
558
|
+
out.sourceMap.description = modelSM.description;
|
559
|
+
out.sourceMap.parameters = modelSM.parameters;
|
560
|
+
out.sourceMap.body = modelSM.body;
|
561
|
+
out.sourceMap.schema = modelSM.schema;
|
584
562
|
|
585
563
|
if (isPayloadContentType && !isModelContentType) {
|
586
|
-
out.
|
564
|
+
out.sourceMap.headers.collection.insert(out.sourceMap.headers.collection.end(), modelSM.headers.collection.begin(), modelSM.headers.collection.end());
|
587
565
|
} else {
|
588
|
-
out.
|
566
|
+
out.sourceMap.headers = modelSM.headers;
|
567
|
+
}
|
568
|
+
}
|
569
|
+
}
|
570
|
+
|
571
|
+
/**
|
572
|
+
* \brief Checks request given as out
|
573
|
+
* \param node Markdown node
|
574
|
+
* \param pd Section parser state
|
575
|
+
* \param out Processed output
|
576
|
+
*/
|
577
|
+
static void checkRequest(const MarkdownNodeIterator& node,
|
578
|
+
SectionParserData& pd,
|
579
|
+
const ParseResultRef<Payload>& out) {
|
580
|
+
|
581
|
+
bool warnEmptyBody = false;
|
582
|
+
|
583
|
+
mdp::ByteBuffer contentLength;
|
584
|
+
mdp::ByteBuffer transferEncoding;
|
585
|
+
|
586
|
+
for (HeaderIterator it = out.node.headers.begin();
|
587
|
+
it != out.node.headers.end();
|
588
|
+
++it) {
|
589
|
+
|
590
|
+
if (it->first == HTTPHeaderName::ContentLength) {
|
591
|
+
contentLength = it->second;
|
592
|
+
}
|
593
|
+
|
594
|
+
if (it->first == HTTPHeaderName::TransferEncoding) {
|
595
|
+
transferEncoding = it->second;
|
589
596
|
}
|
590
|
-
|
591
|
-
out.node.body = model.body;
|
592
|
-
out.node.schema = model.schema;
|
597
|
+
}
|
593
598
|
|
594
|
-
|
599
|
+
if (out.node.body.empty() && out.node.reference.meta.state != Reference::StatePending) {
|
595
600
|
|
596
|
-
|
601
|
+
// Warn when content-length or transfer-encoding is specified or both headers and body are empty
|
602
|
+
if (out.node.headers.empty()) {
|
603
|
+
warnEmptyBody = true;
|
604
|
+
} else {
|
605
|
+
warnEmptyBody = !contentLength.empty() || !transferEncoding.empty();
|
606
|
+
}
|
597
607
|
|
598
|
-
|
599
|
-
out.sourceMap.parameters = modelSM.parameters;
|
600
|
-
out.sourceMap.body = modelSM.body;
|
601
|
-
out.sourceMap.schema = modelSM.schema;
|
608
|
+
if (warnEmptyBody) {
|
602
609
|
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
610
|
+
// WARN: empty body
|
611
|
+
std::stringstream ss;
|
612
|
+
ss << "empty " << SectionName(RequestSectionType) << " " << SectionName(BodySectionType);
|
613
|
+
|
614
|
+
if (!contentLength.empty()) {
|
615
|
+
ss << ", expected " << SectionName(BodySectionType) << " for '" << contentLength << "' Content-Length";
|
616
|
+
} else if (!transferEncoding.empty()) {
|
617
|
+
ss << ", expected " << SectionName(BodySectionType) << " for '" << transferEncoding << "' Transfer-Encoding";
|
607
618
|
}
|
619
|
+
|
620
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
621
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
622
|
+
EmptyDefinitionWarning,
|
623
|
+
sourceMap));
|
608
624
|
}
|
625
|
+
}
|
626
|
+
}
|
609
627
|
|
610
|
-
|
628
|
+
/**
|
629
|
+
* \brief Checks response given as out
|
630
|
+
* \param node Markdown node
|
631
|
+
* \param pd Section parser state
|
632
|
+
* \param out Processed output
|
633
|
+
*/
|
634
|
+
static void checkResponse(const MarkdownNodeIterator& node,
|
635
|
+
SectionParserData& pd,
|
636
|
+
const ParseResultRef<Payload>& out) {
|
637
|
+
|
638
|
+
HTTPStatusCode code = 200;
|
639
|
+
|
640
|
+
if (!out.node.name.empty()) {
|
641
|
+
std::stringstream(out.node.name) >> code;
|
611
642
|
}
|
612
643
|
|
613
|
-
|
644
|
+
StatusCodeTraits statusCodeTraits = GetStatusCodeTrait(code);
|
645
|
+
|
646
|
+
if (!statusCodeTraits.allowBody &&
|
647
|
+
!out.node.body.empty() &&
|
648
|
+
out.node.reference.meta.state != Reference::StatePending) {
|
649
|
+
|
650
|
+
// WARN: not empty body
|
651
|
+
std::stringstream ss;
|
652
|
+
ss << "the " << code << " response MUST NOT include a " << SectionName(BodySectionType);
|
653
|
+
|
654
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
655
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
656
|
+
EmptyDefinitionWarning,
|
657
|
+
sourceMap));
|
658
|
+
}
|
614
659
|
}
|
615
660
|
|
616
661
|
/**
|