redsnow 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.gitmodules +3 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +62 -0
- data/Rakefile +36 -0
- data/Vagrantfile +20 -0
- data/ext/snowcrash/Makefile +64 -0
- data/ext/snowcrash/Vagrantfile +20 -0
- data/ext/snowcrash/bin/snowcrash +0 -0
- data/ext/snowcrash/common.gypi +163 -0
- data/ext/snowcrash/config.gypi +10 -0
- data/ext/snowcrash/config.mk +5 -0
- data/ext/snowcrash/configure +213 -0
- data/ext/snowcrash/provisioning.sh +15 -0
- data/ext/snowcrash/snowcrash.gyp +141 -0
- data/ext/snowcrash/src/ActionParser.h +503 -0
- data/ext/snowcrash/src/AssetParser.h +215 -0
- data/ext/snowcrash/src/BlockUtility.h +186 -0
- data/ext/snowcrash/src/Blueprint.h +283 -0
- data/ext/snowcrash/src/BlueprintParser.h +347 -0
- data/ext/snowcrash/src/BlueprintParserCore.h +190 -0
- data/ext/snowcrash/src/BlueprintSection.h +140 -0
- data/ext/snowcrash/src/BlueprintUtility.h +126 -0
- data/ext/snowcrash/src/CBlueprint.cc +600 -0
- data/ext/snowcrash/src/CBlueprint.h +354 -0
- data/ext/snowcrash/src/CSourceAnnotation.cc +140 -0
- data/ext/snowcrash/src/CSourceAnnotation.h +106 -0
- data/ext/snowcrash/src/CodeBlockUtility.h +189 -0
- data/ext/snowcrash/src/DescriptionSectionUtility.h +156 -0
- data/ext/snowcrash/src/HTTP.cc +46 -0
- data/ext/snowcrash/src/HTTP.h +105 -0
- data/ext/snowcrash/src/HeaderParser.h +289 -0
- data/ext/snowcrash/src/ListBlockUtility.h +273 -0
- data/ext/snowcrash/src/ListUtility.h +95 -0
- data/ext/snowcrash/src/MarkdownBlock.cc +176 -0
- data/ext/snowcrash/src/MarkdownBlock.h +93 -0
- data/ext/snowcrash/src/MarkdownParser.cc +266 -0
- data/ext/snowcrash/src/MarkdownParser.h +88 -0
- data/ext/snowcrash/src/ParameterDefinitonParser.h +570 -0
- data/ext/snowcrash/src/ParametersParser.h +252 -0
- data/ext/snowcrash/src/Parser.cc +71 -0
- data/ext/snowcrash/src/Parser.h +29 -0
- data/ext/snowcrash/src/ParserCore.cc +120 -0
- data/ext/snowcrash/src/ParserCore.h +82 -0
- data/ext/snowcrash/src/PayloadParser.h +672 -0
- data/ext/snowcrash/src/Platform.h +54 -0
- data/ext/snowcrash/src/RegexMatch.h +32 -0
- data/ext/snowcrash/src/ResourceGroupParser.h +195 -0
- data/ext/snowcrash/src/ResourceParser.h +584 -0
- data/ext/snowcrash/src/SectionUtility.h +142 -0
- data/ext/snowcrash/src/Serialize.cc +52 -0
- data/ext/snowcrash/src/Serialize.h +69 -0
- data/ext/snowcrash/src/SerializeJSON.cc +601 -0
- data/ext/snowcrash/src/SerializeJSON.h +21 -0
- data/ext/snowcrash/src/SerializeYAML.cc +336 -0
- data/ext/snowcrash/src/SerializeYAML.h +21 -0
- data/ext/snowcrash/src/SourceAnnotation.h +177 -0
- data/ext/snowcrash/src/StringUtility.h +109 -0
- data/ext/snowcrash/src/SymbolTable.h +83 -0
- data/ext/snowcrash/src/UriTemplateParser.cc +195 -0
- data/ext/snowcrash/src/UriTemplateParser.h +243 -0
- data/ext/snowcrash/src/Version.h +39 -0
- data/ext/snowcrash/src/csnowcrash.cc +23 -0
- data/ext/snowcrash/src/csnowcrash.h +38 -0
- data/ext/snowcrash/src/posix/RegexMatch.cc +99 -0
- data/ext/snowcrash/src/snowcrash.cc +18 -0
- data/ext/snowcrash/src/snowcrash.h +41 -0
- data/ext/snowcrash/src/snowcrash/snowcrash.cc +170 -0
- data/ext/snowcrash/src/win/RegexMatch.cc +78 -0
- data/ext/snowcrash/sundown/CONTRIBUTING.md +10 -0
- data/ext/snowcrash/sundown/Makefile +83 -0
- data/ext/snowcrash/sundown/Makefile.win +33 -0
- data/ext/snowcrash/sundown/examples/smartypants.c +72 -0
- data/ext/snowcrash/sundown/examples/sundown.c +80 -0
- data/ext/snowcrash/sundown/html/houdini.h +37 -0
- data/ext/snowcrash/sundown/html/houdini_href_e.c +108 -0
- data/ext/snowcrash/sundown/html/houdini_html_e.c +84 -0
- data/ext/snowcrash/sundown/html/html.c +647 -0
- data/ext/snowcrash/sundown/html/html.h +77 -0
- data/ext/snowcrash/sundown/html/html_smartypants.c +389 -0
- data/ext/snowcrash/sundown/html_block_names.txt +25 -0
- data/ext/snowcrash/sundown/src/autolink.c +297 -0
- data/ext/snowcrash/sundown/src/autolink.h +51 -0
- data/ext/snowcrash/sundown/src/buffer.c +225 -0
- data/ext/snowcrash/sundown/src/buffer.h +96 -0
- data/ext/snowcrash/sundown/src/html_blocks.h +206 -0
- data/ext/snowcrash/sundown/src/markdown.c +2701 -0
- data/ext/snowcrash/sundown/src/markdown.h +147 -0
- data/ext/snowcrash/sundown/src/src_map.c +200 -0
- data/ext/snowcrash/sundown/src/src_map.h +58 -0
- data/ext/snowcrash/sundown/src/stack.c +81 -0
- data/ext/snowcrash/sundown/src/stack.h +29 -0
- data/ext/snowcrash/sundown/sundown.def +20 -0
- data/ext/snowcrash/tools/gyp/AUTHORS +11 -0
- data/ext/snowcrash/tools/gyp/DEPS +24 -0
- data/ext/snowcrash/tools/gyp/OWNERS +1 -0
- data/ext/snowcrash/tools/gyp/PRESUBMIT.py +120 -0
- data/ext/snowcrash/tools/gyp/buildbot/buildbot_run.py +190 -0
- data/ext/snowcrash/tools/gyp/codereview.settings +10 -0
- data/ext/snowcrash/tools/gyp/data/win/large-pdb-shim.cc +12 -0
- data/ext/snowcrash/tools/gyp/gyp +8 -0
- data/ext/snowcrash/tools/gyp/gyp.bat +5 -0
- data/ext/snowcrash/tools/gyp/gyp_main.py +18 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSNew.py +340 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSProject.py +208 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSSettings.py +1063 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSToolFile.py +58 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUserFile.py +147 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUtil.py +267 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSVersion.py +409 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.py +537 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/common.py +521 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/easy_xml.py +157 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/flock_tool.py +49 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.py +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/android.py +1069 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/cmake.py +1143 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +81 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/eclipse.py +335 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypd.py +87 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypsh.py +56 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.py +2181 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/msvs.py +3335 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/ninja.py +2156 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.py +1224 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/input.py +2809 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/mac_tool.py +510 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/msvs_emulation.py +972 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/ninja_syntax.py +160 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/ordered_dict.py +289 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/win_tool.py +292 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.py +1440 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.py +2889 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xml_fix.py +69 -0
- data/ext/snowcrash/tools/gyp/pylintrc +307 -0
- data/ext/snowcrash/tools/gyp/samples/samples +81 -0
- data/ext/snowcrash/tools/gyp/samples/samples.bat +5 -0
- data/ext/snowcrash/tools/gyp/setup.py +19 -0
- data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.pbfilespec +27 -0
- data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.xclangspec +226 -0
- data/ext/snowcrash/tools/gyp/tools/emacs/gyp.el +252 -0
- data/ext/snowcrash/tools/gyp/tools/graphviz.py +100 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_gyp.py +155 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_sln.py +168 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_vcproj.py +329 -0
- data/ext/snowcrash/tools/homebrew/snowcrash.rb +11 -0
- data/ext/snowcrash/vcbuild.bat +184 -0
- data/lib/redsnow.rb +31 -0
- data/lib/redsnow/binding.rb +132 -0
- data/lib/redsnow/blueprint.rb +365 -0
- data/lib/redsnow/object.rb +18 -0
- data/lib/redsnow/parseresult.rb +107 -0
- data/lib/redsnow/version.rb +4 -0
- data/provisioning.sh +20 -0
- data/redsnow.gemspec +35 -0
- data/test/_helper.rb +15 -0
- data/test/fixtures/sample-api-ast.json +97 -0
- data/test/fixtures/sample-api.apib +20 -0
- data/test/redsnow_binding_test.rb +35 -0
- data/test/redsnow_parseresult_test.rb +50 -0
- data/test/redsnow_test.rb +285 -0
- metadata +358 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ParserCore.h
|
|
3
|
+
// snowcrash
|
|
4
|
+
//
|
|
5
|
+
// Created by Zdenek Nemec on 5/4/13.
|
|
6
|
+
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifndef SNOWCRASH_PARSERCORE_H
|
|
10
|
+
#define SNOWCRASH_PARSERCORE_H
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <vector>
|
|
14
|
+
#include "SourceAnnotation.h"
|
|
15
|
+
#include "Platform.h"
|
|
16
|
+
|
|
17
|
+
namespace snowcrash {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* \brief Textual source data byte buffer. A markdown-formatted text.
|
|
21
|
+
*/
|
|
22
|
+
typedef std::string SourceData;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* \brief A byte range of data within the source data buffer.
|
|
26
|
+
*
|
|
27
|
+
* Important note: All ranges are in bytes not characters.
|
|
28
|
+
*/
|
|
29
|
+
struct SourceDataRange {
|
|
30
|
+
size_t location;
|
|
31
|
+
size_t length;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* \brief A block of source data bytes - a byte map.
|
|
36
|
+
*
|
|
37
|
+
* NOTE: The block does not have to be continuous.
|
|
38
|
+
* Data Blocks are in bytes not characters.
|
|
39
|
+
*/
|
|
40
|
+
typedef std::vector<SourceDataRange> SourceDataBlock;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* \brief Create a %SourceDataBlock with a range.
|
|
44
|
+
* \param loc A location in source data buffer.
|
|
45
|
+
* \param len Length of the range.
|
|
46
|
+
*/
|
|
47
|
+
SourceDataBlock MakeSourceDataBlock(size_t loc, size_t len);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* \brief Append %SourceDataBlock to existing block, merging continuous blocks.
|
|
51
|
+
* \param destination A block to append to.
|
|
52
|
+
* \param append A block to be appended.
|
|
53
|
+
*/
|
|
54
|
+
void AppendSourceDataBlock(SourceDataBlock& destination, const SourceDataBlock& append);
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* \brief A generic pair of two blocks
|
|
58
|
+
*/
|
|
59
|
+
typedef std::pair<SourceDataBlock, SourceDataBlock> SourceDataBlockPair;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* \brief Splits %SourceDataBlock into two blocks.
|
|
63
|
+
* \param block A block to be split.
|
|
64
|
+
* \param len The length of first block after which the split occurs.
|
|
65
|
+
*/
|
|
66
|
+
SourceDataBlockPair SplitSourceDataBlock(const SourceDataBlock& block, size_t len);
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* \brief Maps range of source data bytes into range of characters
|
|
70
|
+
*/
|
|
71
|
+
SourceCharactersRange MapSourceDataRange(const SourceDataRange& range, const SourceData& data);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* \brief Maps block of source data bytes into block of characters.
|
|
75
|
+
* \param block A %SourceDataBlock to map into %SourceCharactersBlock
|
|
76
|
+
* \param data A mapped source data.
|
|
77
|
+
* \returns A character-map constructed from given byte map
|
|
78
|
+
*/
|
|
79
|
+
SourceCharactersBlock MapSourceDataBlock(const SourceDataBlock& block, const SourceData& data);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#endif
|
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PayloadParser.h
|
|
3
|
+
// snowcrash
|
|
4
|
+
//
|
|
5
|
+
// Created by Zdenek Nemec on 5/7/13.
|
|
6
|
+
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#ifndef SNOWCRASH_PARSEPAYLOAD_H
|
|
10
|
+
#define SNOWCRASH_PARSEPAYLOAD_H
|
|
11
|
+
|
|
12
|
+
#include <algorithm>
|
|
13
|
+
#include <sstream>
|
|
14
|
+
#include "BlueprintParserCore.h"
|
|
15
|
+
#include "Blueprint.h"
|
|
16
|
+
#include "RegexMatch.h"
|
|
17
|
+
#include "AssetParser.h"
|
|
18
|
+
#include "HeaderParser.h"
|
|
19
|
+
#include "DescriptionSectionUtility.h"
|
|
20
|
+
#include "StringUtility.h"
|
|
21
|
+
#include "BlockUtility.h"
|
|
22
|
+
|
|
23
|
+
/** Media type in brackets regex */
|
|
24
|
+
#define MEDIA_TYPE "([[:blank:]]*\\(([^\\)]*)\\))"
|
|
25
|
+
|
|
26
|
+
namespace snowcrashconst {
|
|
27
|
+
|
|
28
|
+
/** Request matching regex */
|
|
29
|
+
const char* const RequestRegex = "^[[:blank:]]*[Rr]equest" SYMBOL_IDENTIFIER "?" MEDIA_TYPE "?[[:blank:]]*";
|
|
30
|
+
|
|
31
|
+
/** Response matching regex */
|
|
32
|
+
const char* const ResponseRegex = "^[[:blank:]]*[Rr]esponse([[:blank:][:digit:]]+)?" MEDIA_TYPE "?[[:blank:]]*";
|
|
33
|
+
|
|
34
|
+
/** Object matching regex */
|
|
35
|
+
const char* const ObjectRegex = "^[[:blank:]]*" SYMBOL_IDENTIFIER "[Oo]bject" MEDIA_TYPE "?[[:blank:]]*$";
|
|
36
|
+
|
|
37
|
+
/** Model matching regex */
|
|
38
|
+
const char* const ModelRegex = "^[[:blank:]]*" SYMBOL_IDENTIFIER "?[Mm]odel" MEDIA_TYPE "?[[:blank:]]*";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
namespace snowcrash {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Payload signature
|
|
45
|
+
*/
|
|
46
|
+
enum PayloadSignature {
|
|
47
|
+
UndefinedPayloadSignature, /// < Undefined payload.
|
|
48
|
+
NoPayloadSignature, /// < Not a payload.
|
|
49
|
+
RequestPayloadSignature, /// < Request payload.
|
|
50
|
+
ResponsePayloadSignature, /// < Response payload.
|
|
51
|
+
ObjectPayloadSignature, /// < Resource object payload.
|
|
52
|
+
ModelPayloadSignature /// < Resource Model payload.
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* \brief Query the payload signature of a given block.
|
|
57
|
+
* \param begin The begin of the block to be queried.
|
|
58
|
+
* \param end The end of the markdown block buffer.
|
|
59
|
+
* \param name A buffer to retrieve payload name into.
|
|
60
|
+
* \param mediaType A buffer to retrieve payload media type into.
|
|
61
|
+
* \return The %PayloadSignature of the given block.
|
|
62
|
+
*/
|
|
63
|
+
FORCEINLINE PayloadSignature GetPayloadSignature(const BlockIterator& begin,
|
|
64
|
+
const BlockIterator& end,
|
|
65
|
+
Name& name,
|
|
66
|
+
SourceData& mediaType) {
|
|
67
|
+
|
|
68
|
+
if (begin->type == ListBlockBeginType || begin->type == ListItemBlockBeginType) {
|
|
69
|
+
|
|
70
|
+
BlockIterator cur = ListItemNameBlock(begin, end);
|
|
71
|
+
if (cur == end)
|
|
72
|
+
return NoPayloadSignature;
|
|
73
|
+
|
|
74
|
+
if (cur->type != ParagraphBlockType &&
|
|
75
|
+
cur->type != ListItemBlockEndType)
|
|
76
|
+
return NoPayloadSignature;
|
|
77
|
+
|
|
78
|
+
std::string content = GetFirstLine(cur->content);
|
|
79
|
+
|
|
80
|
+
CaptureGroups captureGroups;
|
|
81
|
+
if (RegexCapture(content, snowcrashconst::RequestRegex, captureGroups, 5)) {
|
|
82
|
+
name = captureGroups[1];
|
|
83
|
+
TrimString(name);
|
|
84
|
+
mediaType = captureGroups[3];
|
|
85
|
+
return RequestPayloadSignature;
|
|
86
|
+
}
|
|
87
|
+
else if (RegexCapture(content, snowcrashconst::ResponseRegex, captureGroups, 5)) {
|
|
88
|
+
name = captureGroups[1];
|
|
89
|
+
TrimString(name);
|
|
90
|
+
mediaType = captureGroups[3];
|
|
91
|
+
return ResponsePayloadSignature;
|
|
92
|
+
}
|
|
93
|
+
else if (RegexCapture(content, snowcrashconst::ObjectRegex, captureGroups, 5)) {
|
|
94
|
+
name = captureGroups[1];
|
|
95
|
+
TrimString(name);
|
|
96
|
+
mediaType = captureGroups[3];
|
|
97
|
+
return ObjectPayloadSignature;
|
|
98
|
+
}
|
|
99
|
+
else if (RegexCapture(content, snowcrashconst::ModelRegex, captureGroups, 5)) {
|
|
100
|
+
name = captureGroups[1];
|
|
101
|
+
TrimString(name);
|
|
102
|
+
mediaType = captureGroups[3];
|
|
103
|
+
return ModelPayloadSignature;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return NoPayloadSignature;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns true if given block has any payload signature, false otherwise.
|
|
112
|
+
*/
|
|
113
|
+
FORCEINLINE bool HasPayloadSignature(const BlockIterator& begin,
|
|
114
|
+
const BlockIterator& end) {
|
|
115
|
+
Name name;
|
|
116
|
+
SourceData mediaType;
|
|
117
|
+
PayloadSignature signature = GetPayloadSignature(begin, end, name, mediaType);
|
|
118
|
+
return signature != NoPayloadSignature;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Retruns true if given block has any payload signature and
|
|
123
|
+
* is written in the abbreviated form. False otherwise.
|
|
124
|
+
*/
|
|
125
|
+
FORCEINLINE bool HasPayloadAssetSignature(const BlockIterator& begin,
|
|
126
|
+
const BlockIterator& end) {
|
|
127
|
+
if (!HasPayloadSignature(begin, end))
|
|
128
|
+
return false;
|
|
129
|
+
|
|
130
|
+
return !HasNestedListBlock(begin, end);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Classifier of internal list items, payload context.
|
|
135
|
+
*/
|
|
136
|
+
template <>
|
|
137
|
+
FORCEINLINE SectionType ClassifyInternaListBlock<Payload>(const BlockIterator& begin,
|
|
138
|
+
const BlockIterator& end) {
|
|
139
|
+
|
|
140
|
+
AssetSignature asset = GetAssetSignature(begin, end);
|
|
141
|
+
if (asset == BodyAssetSignature)
|
|
142
|
+
return BodySectionType;
|
|
143
|
+
else if (asset == SchemaAssetSignature)
|
|
144
|
+
return SchemaSectionType;
|
|
145
|
+
|
|
146
|
+
if (HasHeaderSignature(begin, end))
|
|
147
|
+
return HeadersSectionType;
|
|
148
|
+
|
|
149
|
+
return UndefinedSectionType;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Children blocks classifier */
|
|
153
|
+
template <>
|
|
154
|
+
FORCEINLINE SectionType ClassifyChildrenListBlock<Payload>(const BlockIterator& begin,
|
|
155
|
+
const BlockIterator& end) {
|
|
156
|
+
|
|
157
|
+
SectionType type = ClassifyInternaListBlock<Payload>(begin, end);
|
|
158
|
+
if (type != UndefinedSectionType)
|
|
159
|
+
return type;
|
|
160
|
+
|
|
161
|
+
return UndefinedSectionType;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Block Classifier, payload context.
|
|
166
|
+
*/
|
|
167
|
+
template <>
|
|
168
|
+
FORCEINLINE SectionType ClassifyBlock<Payload>(const BlockIterator& begin,
|
|
169
|
+
const BlockIterator& end,
|
|
170
|
+
const SectionType& context) {
|
|
171
|
+
|
|
172
|
+
if (context == UndefinedSectionType) {
|
|
173
|
+
|
|
174
|
+
Name name;
|
|
175
|
+
SourceData mediaType;
|
|
176
|
+
PayloadSignature payload = GetPayloadSignature(begin, end, name, mediaType);
|
|
177
|
+
if (payload == RequestPayloadSignature) {
|
|
178
|
+
|
|
179
|
+
return (HasNestedListBlock(begin, end)) ? RequestSectionType : RequestBodySectionType;
|
|
180
|
+
}
|
|
181
|
+
else if (payload == ResponsePayloadSignature) {
|
|
182
|
+
|
|
183
|
+
return (HasNestedListBlock(begin, end)) ? ResponseSectionType : ResponseBodySectionType;
|
|
184
|
+
}
|
|
185
|
+
else if (payload == ObjectPayloadSignature) {
|
|
186
|
+
|
|
187
|
+
return (HasNestedListBlock(begin, end)) ? ObjectSectionType : ObjectBodySectionType;
|
|
188
|
+
}
|
|
189
|
+
else if (payload == ModelPayloadSignature) {
|
|
190
|
+
|
|
191
|
+
return (HasNestedListBlock(begin, end)) ? ModelSectionType : ModelBodySectionType;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
else if (context == RequestSectionType ||
|
|
196
|
+
context == ResponseSectionType ||
|
|
197
|
+
context == ObjectSectionType ||
|
|
198
|
+
context == ModelSectionType) {
|
|
199
|
+
|
|
200
|
+
// SectionType closure
|
|
201
|
+
if (begin->type == ListItemBlockEndType ||
|
|
202
|
+
begin->type == ListBlockEndType)
|
|
203
|
+
return UndefinedSectionType;
|
|
204
|
+
|
|
205
|
+
SectionType listSection = ClassifyInternaListBlock<Payload>(begin, end);
|
|
206
|
+
if (listSection != UndefinedSectionType)
|
|
207
|
+
return listSection;
|
|
208
|
+
|
|
209
|
+
// Adjacent list item
|
|
210
|
+
if (begin->type == ListItemBlockBeginType)
|
|
211
|
+
return UndefinedSectionType;
|
|
212
|
+
}
|
|
213
|
+
else if (context == HeadersSectionType ||
|
|
214
|
+
context == BodySectionType ||
|
|
215
|
+
context == SchemaSectionType ||
|
|
216
|
+
context == ForeignSectionType) {
|
|
217
|
+
|
|
218
|
+
// SectionType closure
|
|
219
|
+
if (begin->type == ListItemBlockEndType ||
|
|
220
|
+
begin->type == ListBlockEndType)
|
|
221
|
+
return UndefinedSectionType;
|
|
222
|
+
|
|
223
|
+
SectionType listSection = ClassifyInternaListBlock<Payload>(begin, end);
|
|
224
|
+
if (listSection != UndefinedSectionType)
|
|
225
|
+
return listSection;
|
|
226
|
+
|
|
227
|
+
if (HasPayloadAssetSignature(begin, end))
|
|
228
|
+
return UndefinedSectionType;
|
|
229
|
+
|
|
230
|
+
return ForeignSectionType;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return (context == RequestSectionType ||
|
|
234
|
+
context == ResponseSectionType ||
|
|
235
|
+
context == ObjectSectionType ||
|
|
236
|
+
context == ModelSectionType) ? context : UndefinedSectionType;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Payload section parser.
|
|
241
|
+
*/
|
|
242
|
+
template<>
|
|
243
|
+
struct SectionParser<Payload> {
|
|
244
|
+
|
|
245
|
+
static ParseSectionResult ParseSection(const BlueprintSection& section,
|
|
246
|
+
const BlockIterator& cur,
|
|
247
|
+
BlueprintParserCore& parser,
|
|
248
|
+
Payload& payload) {
|
|
249
|
+
|
|
250
|
+
ParseSectionResult result = std::make_pair(Result(), cur);
|
|
251
|
+
|
|
252
|
+
switch (section.type) {
|
|
253
|
+
case RequestSectionType:
|
|
254
|
+
case ResponseSectionType:
|
|
255
|
+
case ObjectSectionType:
|
|
256
|
+
case ModelSectionType:
|
|
257
|
+
result = HandleDescriptionSectionBlock(section, cur, parser, payload);
|
|
258
|
+
break;
|
|
259
|
+
|
|
260
|
+
case RequestBodySectionType:
|
|
261
|
+
case ResponseBodySectionType:
|
|
262
|
+
case ObjectBodySectionType:
|
|
263
|
+
case ModelBodySectionType:
|
|
264
|
+
result = HandlePayloadAsset(section, cur, parser, payload);
|
|
265
|
+
break;
|
|
266
|
+
|
|
267
|
+
case HeadersSectionType:
|
|
268
|
+
result = HandleHeaders(section, cur, parser, payload);
|
|
269
|
+
break;
|
|
270
|
+
|
|
271
|
+
case BodySectionType:
|
|
272
|
+
case SchemaSectionType:
|
|
273
|
+
result = HandleAsset(section, cur, parser, payload);
|
|
274
|
+
break;
|
|
275
|
+
|
|
276
|
+
case UndefinedSectionType:
|
|
277
|
+
result.second = CloseList(cur, section.bounds.second);
|
|
278
|
+
break;
|
|
279
|
+
|
|
280
|
+
case ForeignSectionType:
|
|
281
|
+
result = HandleForeignSection<Payload>(section, cur, parser.sourceData);
|
|
282
|
+
break;
|
|
283
|
+
|
|
284
|
+
default:
|
|
285
|
+
result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static void Finalize(const SectionBounds& bounds,
|
|
293
|
+
BlueprintParserCore& parser,
|
|
294
|
+
Payload& payload,
|
|
295
|
+
Result& result) {}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* \brief Parse Payload's description blocks.
|
|
299
|
+
* \param section The current section's signature.
|
|
300
|
+
* \param cur The actual position within Markdown block buffer.
|
|
301
|
+
* \param bound Boundaries of Markdown block buffer.
|
|
302
|
+
* \param parser A parser's instance.
|
|
303
|
+
* \param payload An output buffer to write overview description into.
|
|
304
|
+
* \return A block parser section result.
|
|
305
|
+
*/
|
|
306
|
+
static ParseSectionResult HandleDescriptionSectionBlock(const BlueprintSection& section,
|
|
307
|
+
const BlockIterator& cur,
|
|
308
|
+
BlueprintParserCore& parser,
|
|
309
|
+
Payload& payload) {
|
|
310
|
+
|
|
311
|
+
ParseSectionResult result = std::make_pair(Result(), cur);
|
|
312
|
+
BlockIterator sectionCur = cur;
|
|
313
|
+
|
|
314
|
+
// Signature
|
|
315
|
+
if (sectionCur == section.bounds.first) {
|
|
316
|
+
|
|
317
|
+
ProcessSignature(section, sectionCur, parser.sourceData, result.first, payload);
|
|
318
|
+
sectionCur = FirstContentBlock(cur, section.bounds.second);
|
|
319
|
+
|
|
320
|
+
result.second = ++sectionCur;
|
|
321
|
+
return result;
|
|
322
|
+
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Description
|
|
326
|
+
result = ParseDescriptionBlock<Payload>(section,
|
|
327
|
+
sectionCur,
|
|
328
|
+
parser.sourceData,
|
|
329
|
+
payload);
|
|
330
|
+
return result;
|
|
331
|
+
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* \brief Parse an asset.
|
|
336
|
+
* \param section The current section's signature.
|
|
337
|
+
* \param begin The begin of the block to be parsed.
|
|
338
|
+
* \param end The end of the markdown block buffer.
|
|
339
|
+
* \param parser A parser's instance.
|
|
340
|
+
* \param payload An output buffer to save the parsed asset to.
|
|
341
|
+
* \return A block parser section result.
|
|
342
|
+
*/
|
|
343
|
+
static ParseSectionResult HandleAsset(const BlueprintSection& section,
|
|
344
|
+
const BlockIterator& cur,
|
|
345
|
+
BlueprintParserCore& parser,
|
|
346
|
+
Payload& payload) {
|
|
347
|
+
Asset asset;
|
|
348
|
+
ParseSectionResult result = AssetParser::Parse(cur, section.bounds.second, section, parser, asset);
|
|
349
|
+
if (result.first.error.code != Error::OK)
|
|
350
|
+
return result;
|
|
351
|
+
|
|
352
|
+
if (!SetAsset(section.type, asset, payload)) {
|
|
353
|
+
// WARN: asset already set
|
|
354
|
+
std::stringstream ss;
|
|
355
|
+
ss << "ignoring additional " << SectionName(section.type) << " content, content is already defined";
|
|
356
|
+
|
|
357
|
+
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
|
358
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
|
|
359
|
+
result.first.warnings.push_back(Warning(ss.str(),
|
|
360
|
+
RedefinitionWarning,
|
|
361
|
+
sourceBlock));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* \brief Parse payload and abbreviated asset.
|
|
369
|
+
* \param section The current section's signature.
|
|
370
|
+
* \param begin The parsed of the block to be queried.
|
|
371
|
+
* \param end The end of the markdown block buffer.
|
|
372
|
+
* \param parser A parser's instance.
|
|
373
|
+
* \param payload An output buffer to save the parsed paylod and asset into.
|
|
374
|
+
* \return A block parser section result.
|
|
375
|
+
*/
|
|
376
|
+
static ParseSectionResult HandlePayloadAsset(const BlueprintSection& section,
|
|
377
|
+
const BlockIterator& cur,
|
|
378
|
+
BlueprintParserCore& parser,
|
|
379
|
+
Payload& payload) {
|
|
380
|
+
// Try to parse as a Symbol reference
|
|
381
|
+
SymbolName symbol;
|
|
382
|
+
SourceDataBlock symbolSourceMap;
|
|
383
|
+
ParseSectionResult result = ParseSymbolReference(cur, section.bounds, parser, symbol, symbolSourceMap);
|
|
384
|
+
if (result.first.error.code != Error::OK)
|
|
385
|
+
return result;
|
|
386
|
+
|
|
387
|
+
if (result.second != cur) {
|
|
388
|
+
// Process a symbol reference
|
|
389
|
+
ResourceModelSymbolTable::const_iterator symbolEntry = parser.symbolTable.resourceModels.find(symbol);
|
|
390
|
+
if (symbolEntry == parser.symbolTable.resourceModels.end()) {
|
|
391
|
+
|
|
392
|
+
// ERR: Undefined symbol
|
|
393
|
+
std::stringstream ss;
|
|
394
|
+
ss << "undefined symbol '" << symbol << "'";
|
|
395
|
+
result.first.error = Error(ss.str(),
|
|
396
|
+
SymbolError,
|
|
397
|
+
MapSourceDataBlock(symbolSourceMap, parser.sourceData));
|
|
398
|
+
return result;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Retrieve payload from symbol table
|
|
402
|
+
payload = symbolEntry->second;
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
// Parse as an asset
|
|
406
|
+
result = HandleAsset(section, cur, parser, payload);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Retrieve signature
|
|
410
|
+
ProcessSignature(section, cur, parser.sourceData, result.first, payload);
|
|
411
|
+
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* \brief Parse a symbol reference.
|
|
417
|
+
* \param begin The begin of the block to be parsed.
|
|
418
|
+
* \param end The end of the markdown block buffer.
|
|
419
|
+
* \param parser A parser's instance.
|
|
420
|
+
* \param symbolName Output buffer to put parsed symbol's name into.
|
|
421
|
+
* \param symbolSourceMap Source map of the parsed symbol reference.
|
|
422
|
+
* \return A block parser section result.
|
|
423
|
+
*/
|
|
424
|
+
static ParseSectionResult ParseSymbolReference(const BlockIterator& cur,
|
|
425
|
+
const SectionBounds& bounds,
|
|
426
|
+
BlueprintParserCore& parser,
|
|
427
|
+
SymbolName& symbolName,
|
|
428
|
+
SourceDataBlock& symbolSourceMap) {
|
|
429
|
+
|
|
430
|
+
ParseSectionResult result = std::make_pair(Result(), cur);
|
|
431
|
+
BlockIterator sectionCur = cur;
|
|
432
|
+
SourceData content;
|
|
433
|
+
SourceData signature = GetListItemSignature(sectionCur, bounds.second, content);
|
|
434
|
+
if (!content.empty()) {
|
|
435
|
+
sectionCur = ListItemNameBlock(sectionCur, bounds.second);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
sectionCur = FirstContentBlock(cur, bounds.second);
|
|
439
|
+
if (sectionCur == bounds.second ||
|
|
440
|
+
sectionCur->type != ParagraphBlockType)
|
|
441
|
+
return result;
|
|
442
|
+
|
|
443
|
+
// Try the next block
|
|
444
|
+
if (++sectionCur == bounds.second ||
|
|
445
|
+
sectionCur->type != ParagraphBlockType)
|
|
446
|
+
return result;
|
|
447
|
+
|
|
448
|
+
content = sectionCur->content;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
TrimString(content);
|
|
452
|
+
SymbolName symbol;
|
|
453
|
+
if (!GetSymbolReference(content, symbol))
|
|
454
|
+
return result;
|
|
455
|
+
|
|
456
|
+
symbolName = symbol;
|
|
457
|
+
symbolSourceMap = sectionCur->sourceMap;
|
|
458
|
+
|
|
459
|
+
// Close list item
|
|
460
|
+
BlockIterator endCur = cur;
|
|
461
|
+
if (endCur->type == ListBlockBeginType)
|
|
462
|
+
++endCur;
|
|
463
|
+
endCur = SkipToClosingBlock(endCur, bounds.second, ListItemBlockBeginType, ListItemBlockEndType);
|
|
464
|
+
|
|
465
|
+
// Check extraneous content
|
|
466
|
+
if (sectionCur != endCur) {
|
|
467
|
+
++sectionCur;
|
|
468
|
+
for (; sectionCur != endCur; ++sectionCur) {
|
|
469
|
+
|
|
470
|
+
if (sectionCur->type == QuoteBlockBeginType)
|
|
471
|
+
sectionCur = SkipToClosingBlock(sectionCur, endCur, QuoteBlockBeginType, QuoteBlockEndType);
|
|
472
|
+
|
|
473
|
+
if (sectionCur->type == ListBlockBeginType)
|
|
474
|
+
sectionCur = SkipToClosingBlock(sectionCur, endCur, ListBlockBeginType, ListBlockEndType);
|
|
475
|
+
|
|
476
|
+
// WARN: ignoring extraneous content after symbol reference
|
|
477
|
+
std::stringstream ss;
|
|
478
|
+
ss << "ignoring extraneous content after symbol reference";
|
|
479
|
+
ss << ", expected symbol reference only e.g. '[" << symbolName << "][]'";
|
|
480
|
+
|
|
481
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(sectionCur, cur, bounds, parser.sourceData);
|
|
482
|
+
result.first.warnings.push_back(Warning(ss.str(),
|
|
483
|
+
IgnoringWarning,
|
|
484
|
+
sourceBlock));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
endCur = CloseList(sectionCur, bounds.second);
|
|
489
|
+
result.second = endCur;
|
|
490
|
+
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Retrieve and process payload signature.
|
|
496
|
+
*/
|
|
497
|
+
static void ProcessSignature(const BlueprintSection& section,
|
|
498
|
+
const BlockIterator& cur,
|
|
499
|
+
const SourceData& sourceData,
|
|
500
|
+
Result& result,
|
|
501
|
+
Payload& payload) {
|
|
502
|
+
|
|
503
|
+
SourceData remainingContent;
|
|
504
|
+
SourceData signature = GetListItemSignature(cur, section.bounds.second, remainingContent);
|
|
505
|
+
|
|
506
|
+
// Capture name & payload type
|
|
507
|
+
SourceData mediaType;
|
|
508
|
+
GetPayloadSignature(cur, section.bounds.second, payload.name, mediaType);
|
|
509
|
+
|
|
510
|
+
// Check signature
|
|
511
|
+
if (!CheckSignature(section, cur, signature, sourceData, result)) {
|
|
512
|
+
// Clear all readouts
|
|
513
|
+
payload.name.clear();
|
|
514
|
+
mediaType.clear();
|
|
515
|
+
remainingContent.clear();
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Add any extra lines to description unless abbreviated body
|
|
519
|
+
if (!remainingContent.empty() &&
|
|
520
|
+
section.type != RequestBodySectionType &&
|
|
521
|
+
section.type != ResponseBodySectionType) {
|
|
522
|
+
payload.description += remainingContent;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// WARN: missing status code
|
|
526
|
+
if (payload.name.empty() &&
|
|
527
|
+
(section.type == ResponseSectionType || section.type == ResponseBodySectionType)) {
|
|
528
|
+
|
|
529
|
+
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
|
530
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
|
|
531
|
+
result.warnings.push_back(Warning("missing response HTTP status code, assuming 'Response 200'",
|
|
532
|
+
EmptyDefinitionWarning,
|
|
533
|
+
sourceBlock));
|
|
534
|
+
payload.name = "200";
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
// WARN: Object deprecation
|
|
539
|
+
if (section.type == ObjectSectionType || section.type == ObjectBodySectionType) {
|
|
540
|
+
|
|
541
|
+
std::stringstream ss;
|
|
542
|
+
ss << "the 'object' keyword is deprecated and as such it will be removed in a future release, please use the 'model' keyword instead";
|
|
543
|
+
|
|
544
|
+
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
|
545
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
|
|
546
|
+
result.warnings.push_back(Warning(ss.str(),
|
|
547
|
+
DeprecatedWarning,
|
|
548
|
+
sourceBlock));
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (!mediaType.empty()) {
|
|
552
|
+
Header header = std::make_pair(HTTPHeaderName::ContentType, mediaType);
|
|
553
|
+
TrimString(header.second);
|
|
554
|
+
payload.headers.push_back(header);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* \brief Checks and report invalid signature
|
|
560
|
+
* \return True if signature is correct, false otherwise.
|
|
561
|
+
*/
|
|
562
|
+
static bool CheckSignature(const BlueprintSection& section,
|
|
563
|
+
const BlockIterator& cur,
|
|
564
|
+
const SourceData& signature,
|
|
565
|
+
const SourceData& sourceData,
|
|
566
|
+
Result& result) {
|
|
567
|
+
|
|
568
|
+
std::string regex;
|
|
569
|
+
switch (section.type) {
|
|
570
|
+
|
|
571
|
+
case RequestSectionType:
|
|
572
|
+
case RequestBodySectionType:
|
|
573
|
+
regex = snowcrashconst::RequestRegex;
|
|
574
|
+
break;
|
|
575
|
+
|
|
576
|
+
case ResponseBodySectionType:
|
|
577
|
+
case ResponseSectionType:
|
|
578
|
+
regex = snowcrashconst::ResponseRegex;
|
|
579
|
+
break;
|
|
580
|
+
|
|
581
|
+
case ModelSectionType:
|
|
582
|
+
case ModelBodySectionType:
|
|
583
|
+
regex = snowcrashconst::ModelRegex;
|
|
584
|
+
break;
|
|
585
|
+
|
|
586
|
+
default:
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
CaptureGroups captureGroups;
|
|
591
|
+
if (RegexCapture(signature, regex, captureGroups) &&
|
|
592
|
+
!captureGroups.empty()) {
|
|
593
|
+
|
|
594
|
+
std::string target = signature;
|
|
595
|
+
std::string::size_type pos = target.find(captureGroups[0]);
|
|
596
|
+
if (pos != std::string::npos)
|
|
597
|
+
target.replace(pos, captureGroups[0].length(), std::string());
|
|
598
|
+
|
|
599
|
+
TrimString(target);
|
|
600
|
+
if (!target.empty()) {
|
|
601
|
+
// WARN: unable to parse payload signature
|
|
602
|
+
std::stringstream ss;
|
|
603
|
+
ss << "unable to parse " << SectionName(section.type) << " signature, expected ";
|
|
604
|
+
|
|
605
|
+
switch (section.type) {
|
|
606
|
+
|
|
607
|
+
case RequestSectionType:
|
|
608
|
+
case RequestBodySectionType:
|
|
609
|
+
ss << "'request [<identifier>] [(<media type>)]'";
|
|
610
|
+
break;
|
|
611
|
+
|
|
612
|
+
case ResponseBodySectionType:
|
|
613
|
+
case ResponseSectionType:
|
|
614
|
+
ss << "'response [<HTTP status code>] [(<media type>)]'";
|
|
615
|
+
break;
|
|
616
|
+
|
|
617
|
+
case ModelSectionType:
|
|
618
|
+
case ModelBodySectionType:
|
|
619
|
+
ss << "'model [(<media type>)]'";
|
|
620
|
+
break;
|
|
621
|
+
|
|
622
|
+
default:
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
|
627
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
|
|
628
|
+
result.warnings.push_back(Warning(ss.str(),
|
|
629
|
+
FormattingWarning,
|
|
630
|
+
sourceBlock));
|
|
631
|
+
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* \brief Set payload's asset.
|
|
641
|
+
* \return True on success, false when an asset is already set.
|
|
642
|
+
*/
|
|
643
|
+
static bool SetAsset(const SectionType& sectionType, const Asset& asset, Payload& payload) {
|
|
644
|
+
|
|
645
|
+
if (sectionType == BodySectionType ||
|
|
646
|
+
sectionType == RequestBodySectionType ||
|
|
647
|
+
sectionType == ResponseBodySectionType ||
|
|
648
|
+
sectionType == ModelBodySectionType ||
|
|
649
|
+
sectionType == ObjectBodySectionType ||
|
|
650
|
+
sectionType == DanglingBodySectionType) {
|
|
651
|
+
if (!payload.body.empty())
|
|
652
|
+
return false;
|
|
653
|
+
|
|
654
|
+
payload.body = asset;
|
|
655
|
+
}
|
|
656
|
+
else if (sectionType == SchemaSectionType ||
|
|
657
|
+
sectionType == DanglingSchemaSectionType) {
|
|
658
|
+
if (!payload.schema.empty())
|
|
659
|
+
return false;
|
|
660
|
+
|
|
661
|
+
payload.schema = asset;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
return true;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
/** Payload Parser */
|
|
669
|
+
typedef BlockParser<Payload, SectionParser<Payload> > PayloadParser;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
#endif
|