redsnow 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -1
  3. data/README.md +12 -0
  4. data/ext/snowcrash/bin/snowcrash +0 -0
  5. data/ext/snowcrash/ext/markdown-parser/ext/sundown/src/markdown.c +5 -2
  6. data/ext/snowcrash/snowcrash.gyp +7 -2
  7. data/ext/snowcrash/src/ActionParser.h +141 -81
  8. data/ext/snowcrash/src/AssetParser.h +19 -11
  9. data/ext/snowcrash/src/Blueprint.h +44 -14
  10. data/ext/snowcrash/src/BlueprintParser.h +65 -51
  11. data/ext/snowcrash/src/BlueprintSourcemap.h +254 -0
  12. data/ext/snowcrash/src/BlueprintUtility.h +3 -24
  13. data/ext/snowcrash/src/CBlueprint.cc +40 -31
  14. data/ext/snowcrash/src/CBlueprint.h +54 -58
  15. data/ext/snowcrash/src/CBlueprintSourcemap.cc +620 -0
  16. data/ext/snowcrash/src/CBlueprintSourcemap.h +342 -0
  17. data/ext/snowcrash/src/CSourceAnnotation.cc +14 -0
  18. data/ext/snowcrash/src/CodeBlockUtility.h +42 -5
  19. data/ext/snowcrash/src/HeadersParser.h +84 -42
  20. data/ext/snowcrash/src/ParameterParser.h +110 -68
  21. data/ext/snowcrash/src/ParametersParser.h +26 -28
  22. data/ext/snowcrash/src/PayloadParser.h +164 -83
  23. data/ext/snowcrash/src/ResourceGroupParser.h +35 -41
  24. data/ext/snowcrash/src/ResourceParser.h +142 -97
  25. data/ext/snowcrash/src/SectionParser.h +15 -14
  26. data/ext/snowcrash/src/SectionParserData.h +11 -2
  27. data/ext/snowcrash/src/SectionProcessor.h +42 -18
  28. data/ext/snowcrash/src/Serialize.cc +2 -0
  29. data/ext/snowcrash/src/Serialize.h +3 -1
  30. data/ext/snowcrash/src/SerializeJSON.cc +608 -16
  31. data/ext/snowcrash/src/SerializeJSON.h +4 -1
  32. data/ext/snowcrash/src/SerializeYAML.cc +367 -19
  33. data/ext/snowcrash/src/SerializeYAML.h +4 -1
  34. data/ext/snowcrash/src/SymbolTable.h +12 -1
  35. data/ext/snowcrash/src/ValuesParser.h +12 -11
  36. data/ext/snowcrash/src/Version.h +1 -1
  37. data/ext/snowcrash/src/csnowcrash.cc +7 -3
  38. data/ext/snowcrash/src/csnowcrash.h +4 -2
  39. data/ext/snowcrash/src/snowcrash.cc +10 -11
  40. data/ext/snowcrash/src/snowcrash.h +3 -3
  41. data/ext/snowcrash/src/snowcrash/snowcrash.cc +38 -8
  42. data/ext/snowcrash/tools/homebrew/snowcrash.rb +1 -1
  43. data/lib/redsnow.rb +41 -2
  44. data/lib/redsnow/binding.rb +93 -8
  45. data/lib/redsnow/blueprint.rb +48 -25
  46. data/lib/redsnow/parseresult.rb +9 -2
  47. data/lib/redsnow/sourcemap.rb +369 -0
  48. data/lib/redsnow/version.rb +1 -1
  49. data/test/fixtures/sample-api-ast.json +1 -1
  50. data/test/fixtures/sample-api-sourcemap.json +169 -0
  51. data/test/redsnow_binding_test.rb +19 -2
  52. data/test/redsnow_options_test.rb +42 -0
  53. data/test/redsnow_parseresult_test.rb +5 -1
  54. data/test/redsnow_test.rb +5 -0
  55. metadata +11 -2
@@ -34,8 +34,7 @@ namespace snowcrash {
34
34
  static MarkdownNodeIterator parse(const MarkdownNodeIterator& node,
35
35
  const MarkdownNodes& siblings,
36
36
  SectionParserData& pd,
37
- Report& report,
38
- T& out) {
37
+ ParseResult<T>& out) {
39
38
 
40
39
  SectionLayout layout = DefaultSectionLayout;
41
40
  MarkdownNodeIterator cur = Adapter::startingNode(node);
@@ -43,21 +42,21 @@ namespace snowcrash {
43
42
 
44
43
  // Signature node
45
44
  MarkdownNodeIterator lastCur = cur;
46
- cur = SectionProcessor<T>::processSignature(cur, collection, pd, layout, report, out);
45
+ cur = SectionProcessor<T>::processSignature(cur, collection, pd, layout, out);
47
46
 
48
47
  // Exclusive Nested Sections Layout
49
48
  if (layout == ExclusiveNestedSectionLayout) {
50
49
 
51
- cur = parseNestedSections(cur, collection, pd, report, out);
50
+ cur = parseNestedSections(cur, collection, pd, out);
52
51
 
53
- SectionProcessor<T>::finalize(node, pd, report, out);
52
+ SectionProcessor<T>::finalize(node, pd, out);
54
53
 
55
54
  return Adapter::nextStartingNode(node, siblings, cur);
56
55
  }
57
56
 
58
57
  // Parser redirect layout
59
58
  if (layout == RedirectSectionLayout) {
60
- SectionProcessor<T>::finalize(node, pd, report, out);
59
+ SectionProcessor<T>::finalize(node, pd, out);
61
60
 
62
61
  return Adapter::nextStartingNode(node, siblings, cur);
63
62
  }
@@ -71,7 +70,8 @@ namespace snowcrash {
71
70
  SectionProcessor<T>::isDescriptionNode(cur, pd.sectionContext())) {
72
71
 
73
72
  lastCur = cur;
74
- cur = SectionProcessor<T>::processDescription(cur, collection, pd, report, out);
73
+ cur = SectionProcessor<T>::processDescription(cur, collection, pd, out);
74
+
75
75
  if (lastCur == cur)
76
76
  return Adapter::nextStartingNode(node, siblings, cur);
77
77
  }
@@ -81,15 +81,16 @@ namespace snowcrash {
81
81
  SectionProcessor<T>::isContentNode(cur, pd.sectionContext())) {
82
82
 
83
83
  lastCur = cur;
84
- cur = SectionProcessor<T>::processContent(cur, collection, pd, report, out);
84
+ cur = SectionProcessor<T>::processContent(cur, collection, pd, out);
85
+
85
86
  if (lastCur == cur)
86
87
  return Adapter::nextStartingNode(node, siblings, cur);
87
88
  }
88
89
 
89
90
  // Nested Sections
90
- cur = parseNestedSections(cur, collection, pd, report, out);
91
+ cur = parseNestedSections(cur, collection, pd, out);
91
92
 
92
- SectionProcessor<T>::finalize(node, pd, report, out);
93
+ SectionProcessor<T>::finalize(node, pd, out);
93
94
 
94
95
  return Adapter::nextStartingNode(node, siblings, cur);
95
96
  }
@@ -99,8 +100,7 @@ namespace snowcrash {
99
100
  static MarkdownNodeIterator parseNestedSections(const MarkdownNodeIterator& node,
100
101
  const MarkdownNodes& collection,
101
102
  SectionParserData& pd,
102
- Report& report,
103
- T& out) {
103
+ ParseResult<T>& out) {
104
104
 
105
105
  MarkdownNodeIterator cur = node;
106
106
  MarkdownNodeIterator lastCur = cur;
@@ -116,11 +116,12 @@ namespace snowcrash {
116
116
  pd.sectionsContext.push_back(nestedType);
117
117
 
118
118
  if (nestedType != UndefinedSectionType) {
119
- cur = SectionProcessor<T>::processNestedSection(cur, collection, pd, report, out);
119
+ cur = SectionProcessor<T>::processNestedSection(cur, collection, pd, out);
120
120
  }
121
121
  else if (Adapter::nextSkipsUnexpected ||
122
122
  SectionProcessor<T>::isUnexpectedNode(cur, pd.sectionContext())) {
123
- cur = SectionProcessor<T>::processUnexpectedNode(cur, collection, pd, lastSectionType, report, out);
123
+
124
+ cur = SectionProcessor<T>::processUnexpectedNode(cur, collection, pd, lastSectionType, out);
124
125
  }
125
126
 
126
127
  if (cur != collection.end() &&
@@ -9,7 +9,7 @@
9
9
  #ifndef SNOWCRASH_SECTIONPARSERDATA_H
10
10
  #define SNOWCRASH_SECTIONPARSERDATA_H
11
11
 
12
- #include "Blueprint.h"
12
+ #include "BlueprintSourcemap.h"
13
13
  #include "Section.h"
14
14
  #include "SymbolTable.h"
15
15
 
@@ -22,7 +22,8 @@ namespace snowcrash {
22
22
  */
23
23
  enum BlueprintParserOption {
24
24
  RenderDescriptionsOption = (1 << 0), /// < Render Markdown in description.
25
- RequireBlueprintNameOption = (1 << 1) /// < Treat missing blueprint name as error
25
+ RequireBlueprintNameOption = (1 << 1), /// < Treat missing blueprint name as error
26
+ ExportSourcemapOption = (1 << 2) /// < Export source maps AST
26
27
  };
27
28
 
28
29
  typedef unsigned int BlueprintParserOptions;
@@ -44,6 +45,9 @@ namespace snowcrash {
44
45
  /** Symbol Table */
45
46
  SymbolTable symbolTable;
46
47
 
48
+ /** Symbol Table Sourcemap */
49
+ SymbolSourceMapTable symbolSourceMapTable;
50
+
47
51
  /** Source Data */
48
52
  const mdp::ByteBuffer& sourceData;
49
53
 
@@ -71,6 +75,11 @@ namespace snowcrash {
71
75
  return sectionsContext[size-2];
72
76
  }
73
77
 
78
+ /** \returns True if exporting source maps */
79
+ bool exportSourceMap() const {
80
+ return options & ExportSourcemapOption;
81
+ }
82
+
74
83
  private:
75
84
  SectionParserData();
76
85
  SectionParserData(const SectionParserData&);
@@ -30,6 +30,27 @@ namespace snowcrash {
30
30
  RedirectSectionLayout /// Section should be parsed by another parser as whole
31
31
  };
32
32
 
33
+ /**
34
+ * Compound product of parsing a node
35
+ */
36
+ template<typename T>
37
+ struct ParseResult {
38
+ ParseResult(Report& report_,
39
+ T& node_,
40
+ SourceMap<T>& sourceMap_)
41
+ : report(report_), node(node_), sourceMap(sourceMap_) {}
42
+
43
+ ParseResult(Report& report_)
44
+ : report(report_), node(*(new T)), sourceMap(*(new SourceMap<T>)) {}
45
+
46
+ ParseResult()
47
+ : report(*(new Report)), node(*(new T)), sourceMap(*(new SourceMap<T>)) {}
48
+
49
+ Report& report; /// Parser's report
50
+ T& node; /// Parsed AST node
51
+ SourceMap<T>& sourceMap; /// Parsed AST node source map
52
+ };
53
+
33
54
  /*
34
55
  * Forward Declarations
35
56
  */
@@ -58,8 +79,8 @@ namespace snowcrash {
58
79
  const MarkdownNodes& siblings,
59
80
  SectionParserData& pd,
60
81
  SectionLayout& layout,
61
- Report& report,
62
- T& out) {
82
+ ParseResult<T>& out) {
83
+
63
84
  return ++MarkdownNodeIterator(node);
64
85
  }
65
86
 
@@ -67,14 +88,19 @@ namespace snowcrash {
67
88
  static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
68
89
  const MarkdownNodes& siblings,
69
90
  SectionParserData& pd,
70
- Report& report,
71
- T& out) {
91
+ ParseResult<T>& out) {
72
92
 
73
- if (!out.description.empty()) {
74
- TwoNewLines(out.description);
93
+ if (!out.node.description.empty()) {
94
+ TwoNewLines(out.node.description);
75
95
  }
76
96
 
77
- out.description += mdp::MapBytesRangeSet(node->sourceMap, pd.sourceData);
97
+ mdp::ByteBuffer content = mdp::MapBytesRangeSet(node->sourceMap, pd.sourceData);
98
+
99
+ if (pd.exportSourceMap() && !content.empty()) {
100
+ out.sourceMap.description.sourceMap.append(node->sourceMap);
101
+ }
102
+
103
+ out.node.description += content;
78
104
 
79
105
  return ++MarkdownNodeIterator(node);
80
106
  }
@@ -83,8 +109,8 @@ namespace snowcrash {
83
109
  static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
84
110
  const MarkdownNodes& siblings,
85
111
  SectionParserData& pd,
86
- Report& report,
87
- T& out) {
112
+ ParseResult<T>& out) {
113
+
88
114
  return ++MarkdownNodeIterator(node);
89
115
  }
90
116
 
@@ -99,8 +125,8 @@ namespace snowcrash {
99
125
  static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
100
126
  const MarkdownNodes& siblings,
101
127
  SectionParserData& pd,
102
- Report& report,
103
- T& out) {
128
+ ParseResult<T>& out) {
129
+
104
130
  return node;
105
131
  }
106
132
 
@@ -109,8 +135,7 @@ namespace snowcrash {
109
135
  const MarkdownNodes& siblings,
110
136
  SectionParserData& pd,
111
137
  SectionType& lastSectionType,
112
- Report& report,
113
- T& out) {
138
+ ParseResult<T>& out) {
114
139
 
115
140
  // WARN: Ignoring unexpected node
116
141
  std::stringstream ss;
@@ -123,9 +148,9 @@ namespace snowcrash {
123
148
  ss << "ignoring unrecognized block";
124
149
  }
125
150
 
126
- report.warnings.push_back(Warning(ss.str(),
127
- IgnoringWarning,
128
- sourceMap));
151
+ out.report.warnings.push_back(Warning(ss.str(),
152
+ IgnoringWarning,
153
+ sourceMap));
129
154
 
130
155
  return ++MarkdownNodeIterator(node);
131
156
  }
@@ -133,8 +158,7 @@ namespace snowcrash {
133
158
  /** Final validation after processing */
134
159
  static void finalize(const MarkdownNodeIterator& node,
135
160
  SectionParserData& pd,
136
- Report& report,
137
- T& out) {
161
+ ParseResult<T>& out) {
138
162
  }
139
163
 
140
164
  /** \return True if the node is a section description node */
@@ -17,6 +17,8 @@ using namespace snowcrash;
17
17
 
18
18
  const std::string SerializeKey::ASTVersion = "_version";
19
19
  const std::string SerializeKey::Metadata = "metadata";
20
+ const std::string SerializeKey::Reference = "reference";
21
+ const std::string SerializeKey::Id = "id";
20
22
  const std::string SerializeKey::Name = "name";
21
23
  const std::string SerializeKey::Description = "description";
22
24
  const std::string SerializeKey::ResourceGroups = "resourceGroups";
@@ -12,7 +12,7 @@
12
12
  #include <string>
13
13
 
14
14
  /** Version of API Blueprint AST serialization */
15
- #define AST_SERIALIZATION_VERSION "2.0"
15
+ #define AST_SERIALIZATION_VERSION "2.1"
16
16
 
17
17
  namespace snowcrash {
18
18
 
@@ -38,6 +38,8 @@ namespace snowcrash {
38
38
  struct SerializeKey {
39
39
  static const std::string ASTVersion;
40
40
  static const std::string Metadata;
41
+ static const std::string Reference;
42
+ static const std::string Id;
41
43
  static const std::string Name;
42
44
  static const std::string Description;
43
45
  static const std::string ResourceGroups;
@@ -57,6 +57,7 @@ static void serialize(const std::string& key, const std::string& value, size_t l
57
57
  os << ": ";
58
58
 
59
59
  std::string normValue = EscapeDoubleQuotes(value);
60
+
60
61
  if (normValue.find("\n") != std::string::npos)
61
62
  serialize(EscapeNewlines(normValue), os);
62
63
  else
@@ -107,6 +108,95 @@ static void serialize(const std::string& key, const std::string& value, size_t l
107
108
  os << "}";
108
109
  }
109
110
 
111
+ /**
112
+ * \brief Serialize source map without key into output stream
113
+ * \param set Source map
114
+ * \param level Indentation level
115
+ * \param os An output stream to serialize into
116
+ */
117
+ static void serialize(const SourceMapBase& set, size_t level, std::ostream &os)
118
+ {
119
+ os << "[";
120
+
121
+ if (!set.sourceMap.empty()) {
122
+ size_t i = 0;
123
+ os << "\n";
124
+
125
+ for (mdp::RangeSet<mdp::BytesRange>::const_iterator it = set.sourceMap.begin(); it != set.sourceMap.end(); ++i, ++it) {
126
+
127
+ if (i > 0 && i < set.sourceMap.size())
128
+ os << NewLineItemBlock;
129
+
130
+ indent(level + 1, os);
131
+ os << "[" << it->location << ", " << it->length << "]";
132
+ }
133
+
134
+ os << std::endl;
135
+ indent(level, os);
136
+ }
137
+
138
+ os << "]";
139
+ }
140
+
141
+ /**
142
+ * \brief Serialize a key and source map value into output stream.
143
+ * \param key Key to serialize
144
+ * \param value Source Map to serialize
145
+ * \param level Indentation level
146
+ * \param object Flag to indicate whether the pair should be serialized as an object
147
+ * \param os An output stream to serialize into
148
+ */
149
+ static void serialize(const std::string& key, const SourceMapBase& value, size_t level, bool object, std::ostream &os)
150
+ {
151
+ indent(level, os);
152
+
153
+ if (object) {
154
+ os << "{\n";
155
+ indent(level + 1, os);
156
+ }
157
+
158
+ serialize(key, os);
159
+ os << ": ";
160
+
161
+ serialize(value, level, os);
162
+
163
+ if (object) {
164
+ os << "\n";
165
+ indent(level, os);
166
+ os << "}";
167
+ }
168
+ }
169
+
170
+ /**
171
+ * \brief Serialize an array of source maps.
172
+ * \param collection Collection to serialize
173
+ * \param level Level of indentation
174
+ * \param os An output stream to serialize into
175
+ */
176
+ static void serializeSourceMapCollection(const Collection<SourceMap<KeyValuePair> >::type& collection, size_t level, std::ostream &os)
177
+ {
178
+ os << "[";
179
+
180
+ if (!collection.empty()) {
181
+ os << "\n";
182
+ size_t i = 0;
183
+
184
+ for (Collection<SourceMap<KeyValuePair> >::const_iterator it = collection.begin(); it != collection.end(); ++i, ++it) {
185
+
186
+ if (i > 0 && i < collection.size())
187
+ os << NewLineItemBlock;
188
+
189
+ indent(level + 1, os);
190
+ serialize(*it, level + 1, os);
191
+ }
192
+
193
+ os << "\n";
194
+ indent(level, os);
195
+ }
196
+
197
+ os << "]";
198
+ }
199
+
110
200
  /**
111
201
  * \brief Serialize an array of key value pairs.
112
202
  * \param collection Collection to serialize
@@ -116,31 +206,32 @@ static void serialize(const std::string& key, const std::string& value, size_t l
116
206
  static void serializeKeyValueCollection(const Collection<KeyValuePair>::type& collection, size_t level, std::ostream &os)
117
207
  {
118
208
  os << "[";
119
-
209
+
120
210
  if (!collection.empty()) {
121
211
  os << "\n";
122
212
  size_t i = 0;
213
+
123
214
  for (Collection<KeyValuePair>::const_iterator it = collection.begin(); it != collection.end(); ++i, ++it) {
124
-
215
+
125
216
  if (i > 0 && i < collection.size())
126
217
  os << NewLineItemBlock;
127
-
128
-
218
+
129
219
  serialize(it->first, it->second, level + 1, os);
130
220
  }
131
-
221
+
132
222
  os << "\n";
133
223
  indent(level, os);
134
224
  }
135
225
 
136
226
  os << "]";
137
227
  }
228
+
138
229
  /**
139
230
  * \brief Serialize Metadata into output stream.
140
231
  * \param metadata Metadata to serialize
141
232
  * \param os An output stream to serialize into
142
233
  */
143
- static void serialize(const Collection<Metadata>::type& metadata, std::ostream &os)
234
+ static void serialize(const MetadataCollection& metadata, std::ostream &os)
144
235
  {
145
236
  indent(1, os);
146
237
  serialize(SerializeKey::Metadata, os);
@@ -151,13 +242,29 @@ static void serialize(const Collection<Metadata>::type& metadata, std::ostream &
151
242
  os << NewLineItemBlock;
152
243
  }
153
244
 
245
+ /**
246
+ * \brief Serialize Metadata source map into output stream.
247
+ * \param metadata Metadata source map to serialize
248
+ * \param os An output stream to serialize into
249
+ */
250
+ static void serialize(const Collection<SourceMap<Metadata> >::type& metadata, std::ostream &os)
251
+ {
252
+ indent(1, os);
253
+ serialize(SerializeKey::Metadata, os);
254
+ os << ": ";
255
+
256
+ serializeSourceMapCollection(metadata, 1, os);
257
+
258
+ os << NewLineItemBlock;
259
+ }
260
+
154
261
  /**
155
262
  * \brief Serialize Parameters into output stream.
156
263
  * \param prarameters Parameters to serialize.
157
264
  * \param level Level of indentation.
158
265
  * \param os An output stream to serialize into.
159
266
  */
160
- static void serialize(const Collection<Parameter>::type& parameters, size_t level, std::ostream &os)
267
+ static void serialize(const Parameters& parameters, size_t level, std::ostream &os)
161
268
  {
162
269
  indent(level, os);
163
270
  serialize(SerializeKey::Parameters, os);
@@ -166,6 +273,7 @@ static void serialize(const Collection<Parameter>::type& parameters, size_t leve
166
273
  if (!parameters.empty()) {
167
274
  os << "\n";
168
275
  size_t i = 0;
276
+
169
277
  for (Collection<Parameter>::const_iterator it = parameters.begin(); it != parameters.end(); ++i, ++it) {
170
278
 
171
279
  if (i > 0 && i < parameters.size())
@@ -206,7 +314,10 @@ static void serialize(const Collection<Parameter>::type& parameters, size_t leve
206
314
  if (!it->values.empty()) {
207
315
  os << "\n";
208
316
  size_t j = 0;
209
- for (Collection<Value>::const_iterator val_it = it->values.begin(); val_it != it->values.end(); ++j, ++val_it) {
317
+
318
+ for (Collection<Value>::const_iterator val_it = it->values.begin();
319
+ val_it != it->values.end();
320
+ ++j, ++val_it) {
210
321
 
211
322
  if (j > 0 && j < it->values.size())
212
323
  os << NewLineItemBlock;
@@ -234,13 +345,102 @@ static void serialize(const Collection<Parameter>::type& parameters, size_t leve
234
345
  os << "]";
235
346
  }
236
347
 
348
+ /**
349
+ * \brief Serialize Parameters source map into output stream.
350
+ * \param prarameters Parameters source map to serialize.
351
+ * \param level Level of indentation.
352
+ * \param os An output stream to serialize into.
353
+ */
354
+ static void serialize(const Collection<SourceMap<Parameter> >::type& parameters, size_t level, std::ostream &os)
355
+ {
356
+ indent(level, os);
357
+ serialize(SerializeKey::Parameters, os);
358
+ os << ": [";
359
+
360
+ if (!parameters.empty()) {
361
+ os << "\n";
362
+ size_t i = 0;
363
+
364
+ for (Collection<SourceMap<Parameter> >::const_iterator it = parameters.begin(); it != parameters.end(); ++i, ++it) {
365
+
366
+ if (i > 0 && i < parameters.size())
367
+ os << NewLineItemBlock;
368
+
369
+ indent(level + 1, os);
370
+ os << "{\n";
371
+
372
+ // Name
373
+ serialize(SerializeKey::Name, it->name, level + 2, false, os);
374
+ os << NewLineItemBlock;
375
+
376
+ // Description
377
+ serialize(SerializeKey::Description, it->description, level + 2, false, os);
378
+ os << NewLineItemBlock;
379
+
380
+ // Type
381
+ serialize(SerializeKey::Type, it->type, level + 2, false, os);
382
+ os << NewLineItemBlock;
383
+
384
+ // Requried
385
+ serialize(SerializeKey::Required, it->use, level + 2, false, os);
386
+ os << NewLineItemBlock;
387
+
388
+ // Default
389
+ serialize(SerializeKey::Default, it->defaultValue, level + 2, false, os);
390
+ os << NewLineItemBlock;
391
+
392
+ // Example
393
+ serialize(SerializeKey::Example, it->exampleValue, level + 2, false, os);
394
+ os << NewLineItemBlock;
395
+
396
+ // Values
397
+ indent(level + 2, os);
398
+ serialize(SerializeKey::Values, os);
399
+ os << ": [";
400
+
401
+ if (!it->values.collection.empty()) {
402
+ os << "\n";
403
+ size_t j = 0;
404
+
405
+ indent(level + 3, os);
406
+
407
+ for (Collection<SourceMap<Value> >::const_iterator val_it = it->values.collection.begin();
408
+ val_it != it->values.collection.end();
409
+ ++j, ++val_it) {
410
+
411
+ if (j > 0 && j < it->values.collection.size())
412
+ os << NewLineItemBlock;
413
+
414
+ serialize(*val_it, level + 3, os);
415
+ }
416
+
417
+ os << "\n";
418
+ indent(level + 2, os);
419
+ }
420
+
421
+ // Close Values
422
+ os << "]";
423
+
424
+ // Close Key / name object
425
+ os << "\n";
426
+ indent(level + 1, os);
427
+ os << "}";
428
+ }
429
+
430
+ os << std::endl;
431
+ indent(level, os);
432
+ }
433
+
434
+ os << "]";
435
+ }
436
+
237
437
  /**
238
438
  * \brief Serialize HTTP headers into output stream.
239
439
  * \param headers Headers to serialize.
240
440
  * \param level Level of indentation.
241
441
  * \param os An output stream to serialize into.
242
442
  */
243
- static void serialize(const Collection<Header>::type& headers, size_t level, std::ostream &os)
443
+ static void serialize(const Headers& headers, size_t level, std::ostream &os)
244
444
  {
245
445
  indent(level, os);
246
446
  serialize(SerializeKey::Headers, os);
@@ -249,6 +449,21 @@ static void serialize(const Collection<Header>::type& headers, size_t level, std
249
449
  serializeKeyValueCollection(headers, level, os);
250
450
  }
251
451
 
452
+ /**
453
+ * \brief Serialize HTTP headers source map into output stream.
454
+ * \param headers Headers source map to serialize.
455
+ * \param level Level of indentation.
456
+ * \param os An output stream to serialize into.
457
+ */
458
+ static void serialize(const Collection<SourceMap<Header> >::type& headers, size_t level, std::ostream &os)
459
+ {
460
+ indent(level, os);
461
+ serialize(SerializeKey::Headers, os);
462
+ os << ": ";
463
+
464
+ serializeSourceMapCollection(headers, level, os);
465
+ }
466
+
252
467
  /**
253
468
  * \brief Serialize a payload into output stream.
254
469
  * \param payload A payload to serialize.
@@ -257,11 +472,23 @@ static void serialize(const Collection<Header>::type& headers, size_t level, std
257
472
  static void serialize(const Payload& payload, size_t level, std::ostream &os)
258
473
  {
259
474
  os << "{\n";
260
-
475
+
261
476
  // Name
262
477
  serialize(SerializeKey::Name, payload.name, level + 1, false, os);
263
478
  os << NewLineItemBlock;
264
479
 
480
+ // Symbol Reference
481
+ if (!payload.symbol.empty()) {
482
+ indent(level + 1, os);
483
+ os << "\"" << SerializeKey::Reference << "\": {\n";
484
+
485
+ serialize(SerializeKey::Id, payload.symbol, level + 2, false, os);
486
+
487
+ os << "\n";
488
+ indent(level + 1, os);
489
+ os << "}" << NewLineItemBlock;
490
+ }
491
+
265
492
  // Description
266
493
  serialize(SerializeKey::Description, payload.description, level + 1, false, os);
267
494
  os << NewLineItemBlock;
@@ -282,6 +509,45 @@ static void serialize(const Payload& payload, size_t level, std::ostream &os)
282
509
  os << "}";
283
510
  }
284
511
 
512
+ /**
513
+ * \brief Serialize a payload source map into output stream.
514
+ * \param payload A payload source map to serialize.
515
+ * \param os An output stream to serialize into.
516
+ */
517
+ static void serialize(const SourceMap<Payload>& payload, size_t level, std::ostream &os)
518
+ {
519
+ os << "{\n";
520
+
521
+ // Name
522
+ serialize(SerializeKey::Name, payload.name, level + 1, false, os);
523
+ os << NewLineItemBlock;
524
+
525
+ // Symbol Reference
526
+ if (!payload.symbol.sourceMap.empty()) {
527
+ serialize(SerializeKey::Reference, payload.symbol, level + 1, false, os);
528
+ os << NewLineItemBlock;
529
+ }
530
+
531
+ // Description
532
+ serialize(SerializeKey::Description, payload.description, level + 1, false, os);
533
+ os << NewLineItemBlock;
534
+
535
+ // Headers
536
+ serialize(payload.headers.collection, level + 1, os);
537
+ os << NewLineItemBlock;
538
+
539
+ // Body
540
+ serialize(SerializeKey::Body, payload.body, level + 1, false, os);
541
+ os << NewLineItemBlock;
542
+
543
+ // Schema
544
+ serialize(SerializeKey::Schema, payload.schema, level + 1, false, os);
545
+
546
+ os << "\n";
547
+ indent(level, os);
548
+ os << "}";
549
+ }
550
+
285
551
  /**
286
552
  * \brief Serialize a transaction example into output stream.
287
553
  * \param transaction A transaction example to serialize.
@@ -309,6 +575,7 @@ static void serialize(const TransactionExample& example, std::ostream &os)
309
575
  if (!example.requests.empty()) {
310
576
  os << "\n";
311
577
  size_t i = 0;
578
+
312
579
  for (Collection<Request>::const_iterator it = example.requests.begin();
313
580
  it != example.requests.end();
314
581
  ++i, ++it) {
@@ -335,6 +602,7 @@ static void serialize(const TransactionExample& example, std::ostream &os)
335
602
  if (!example.responses.empty()) {
336
603
  os << "\n";
337
604
  size_t i = 0;
605
+
338
606
  for (Collection<Response>::const_iterator it = example.responses.begin();
339
607
  it != example.responses.end();
340
608
  ++i, ++it) {
@@ -357,6 +625,83 @@ static void serialize(const TransactionExample& example, std::ostream &os)
357
625
  os << "}";
358
626
  }
359
627
 
628
+ /**
629
+ * \brief Serialize a transaction example source map into output stream.
630
+ * \param transaction A transaction example source map to serialize.
631
+ * \param os An output stream to serialize into.
632
+ */
633
+ static void serialize(const SourceMap<TransactionExample>& example, std::ostream &os)
634
+ {
635
+ indent(8, os);
636
+ os << "{\n";
637
+
638
+ // Name
639
+ serialize(SerializeKey::Name, example.name, 9, false, os);
640
+ os << NewLineItemBlock;
641
+
642
+ // Description
643
+ serialize(SerializeKey::Description, example.description, 9, false, os);
644
+ os << NewLineItemBlock;
645
+
646
+ // Requests
647
+ indent(9, os);
648
+ serialize(SerializeKey::Requests, os);
649
+ os << ": ";
650
+ os << "[";
651
+
652
+ if (!example.requests.collection.empty()) {
653
+ os << "\n";
654
+ size_t i = 0;
655
+
656
+ for (Collection<SourceMap<Request> >::const_iterator it = example.requests.collection.begin();
657
+ it != example.requests.collection.end();
658
+ ++i, ++it) {
659
+
660
+ if (i > 0 && i < example.requests.collection.size())
661
+ os << NewLineItemBlock;
662
+
663
+ indent(10, os);
664
+ serialize(*it, 10, os);
665
+ }
666
+
667
+ os << "\n";
668
+ indent(9, os);
669
+ }
670
+ os << "]";
671
+ os << NewLineItemBlock;
672
+
673
+ // Responses
674
+ indent(9, os);
675
+ serialize(SerializeKey::Responses, os);
676
+ os << ": ";
677
+ os << "[";
678
+
679
+ if (!example.responses.collection.empty()) {
680
+ os << "\n";
681
+ size_t i = 0;
682
+
683
+ for (Collection<SourceMap<Response> >::const_iterator it = example.responses.collection.begin();
684
+ it != example.responses.collection.end();
685
+ ++i, ++it) {
686
+
687
+ if (i > 0 && i < example.responses.collection.size())
688
+ os << NewLineItemBlock;
689
+
690
+ indent(10, os);
691
+ serialize(*it, 10, os);
692
+ }
693
+
694
+ os << "\n";
695
+ indent(9, os);
696
+ }
697
+ os << "]";
698
+
699
+ // Close the transaction
700
+ os << "\n";
701
+ indent(8, os);
702
+ os << "}";
703
+ }
704
+
360
705
  /**
361
706
  * \brief Serialize an action into output stream.
362
707
  * \param action The action to serialize.
@@ -392,6 +737,7 @@ static void serialize(const Action& action, std::ostream &os)
392
737
  if (!action.examples.empty()) {
393
738
  os << "\n";
394
739
  size_t i = 0;
740
+
395
741
  for (Collection<TransactionExample>::const_iterator it = action.examples.begin();
396
742
  it != action.examples.end();
397
743
  ++i, ++it) {
@@ -415,7 +761,65 @@ static void serialize(const Action& action, std::ostream &os)
415
761
  }
416
762
 
417
763
  /**
418
- * \brief Serialize a resources into output stream.
764
+ * \brief Serialize an action source map into output stream.
765
+ * \param action The action source map to serialize.
766
+ * \param os An output stream to serialize into.
767
+ */
768
+ static void serialize(const SourceMap<Action>& action, std::ostream &os)
769
+ {
770
+ indent(6, os);
771
+ os << "{\n";
772
+
773
+ // Name
774
+ serialize(SerializeKey::Name, action.name, 7, false, os);
775
+ os << NewLineItemBlock;
776
+
777
+ // Description
778
+ serialize(SerializeKey::Description, action.description, 7, false, os);
779
+ os << NewLineItemBlock;
780
+
781
+ // HTTP Method
782
+ serialize(SerializeKey::Method, action.method, 7, false, os);
783
+ os << NewLineItemBlock;
784
+
785
+ // Parameters
786
+ serialize(action.parameters.collection, 7, os);
787
+ os << NewLineItemBlock;
788
+
789
+ // Transactions
790
+ indent(7, os);
791
+ serialize(SerializeKey::Examples, os);
792
+ os << ": ";
793
+ os << "[";
794
+
795
+ if (!action.examples.collection.empty()) {
796
+ os << "\n";
797
+ size_t i = 0;
798
+
799
+ for (Collection<SourceMap<TransactionExample> >::const_iterator it = action.examples.collection.begin();
800
+ it != action.examples.collection.end();
801
+ ++i, ++it) {
802
+
803
+ if (i > 0 && i < action.examples.collection.size())
804
+ os << NewLineItemBlock;
805
+
806
+ serialize(*it, os);
807
+ }
808
+
809
+ os << "\n";
810
+ indent(7, os);
811
+ }
812
+
813
+ os << "]";
814
+
815
+ // Close the action
816
+ os << "\n";
817
+ indent(6, os);
818
+ os << "}";
819
+ }
820
+
821
+ /**
822
+ * \brief Serialize a resource into output stream.
419
823
  * \param resource A resource to serialize
420
824
  * \param os An output stream to serialize into
421
825
  */
@@ -461,8 +865,8 @@ static void serialize(const Resource& resource, std::ostream &os)
461
865
 
462
866
  if (!resource.actions.empty()) {
463
867
  os << "\n";
464
-
465
868
  size_t i = 0;
869
+
466
870
  for (Collection<Action>::const_iterator it = resource.actions.begin();
467
871
  it != resource.actions.end();
468
872
  ++i, ++it) {
@@ -476,6 +880,7 @@ static void serialize(const Resource& resource, std::ostream &os)
476
880
  os << "\n";
477
881
  indent(5, os);
478
882
  }
883
+
479
884
  os << "]";
480
885
 
481
886
  // Close the resource
@@ -484,6 +889,77 @@ static void serialize(const Resource& resource, std::ostream &os)
484
889
  os << "}";
485
890
  }
486
891
 
892
+ /**
893
+ * \brief Serialize a resource source map into output stream.
894
+ * \param resource A resource source map to serialize
895
+ * \param os An output stream to serialize into
896
+ */
897
+ static void serialize(const SourceMap<Resource>& resource, std::ostream &os)
898
+ {
899
+ indent(4, os);
900
+ os << "{\n";
901
+
902
+ // Name
903
+ serialize(SerializeKey::Name, resource.name, 5, false, os);
904
+ os << NewLineItemBlock;
905
+
906
+ // Description
907
+ serialize(SerializeKey::Description, resource.description, 5, false, os);
908
+ os << NewLineItemBlock;
909
+
910
+ // URI template
911
+ serialize(SerializeKey::URITemplate, resource.uriTemplate, 5, false, os);
912
+ os << NewLineItemBlock;
913
+
914
+ // Model
915
+ indent(5, os);
916
+ serialize(SerializeKey::Model, os);
917
+ if (resource.model.name.sourceMap.empty()) {
918
+ os << ": {}";
919
+ }
920
+ else {
921
+ os << ": ";
922
+
923
+ serialize(resource.model, 5, os);
924
+ }
925
+ os << NewLineItemBlock;
926
+
927
+ // Parameters
928
+ serialize(resource.parameters.collection, 5, os);
929
+ os << NewLineItemBlock;
930
+
931
+ // Actions
932
+ indent(5, os);
933
+ serialize(SerializeKey::Actions, os);
934
+ os << ": ";
935
+ os << "[";
936
+
937
+ if (!resource.actions.collection.empty()) {
938
+ os << "\n";
939
+ size_t i = 0;
940
+
941
+ for (Collection<SourceMap<Action> >::const_iterator it = resource.actions.collection.begin();
942
+ it != resource.actions.collection.end();
943
+ ++i, ++it) {
944
+
945
+ if (i > 0 && i < resource.actions.collection.size())
946
+ os << NewLineItemBlock;
947
+
948
+ serialize(*it, os);
949
+ }
950
+
951
+ os << "\n";
952
+ indent(5, os);
953
+ }
954
+
955
+ os << "]";
956
+
957
+ // Close the resource
958
+ os << "\n";
959
+ indent(4, os);
960
+ os << "}";
961
+ }
962
+
487
963
  /**
488
964
  * \brief Serialize a group of resources into output stream.
489
965
  * \param resourceGroup A group to serialize.
@@ -511,6 +987,7 @@ static void serialize(const ResourceGroup& resourceGroup, std::ostream &os)
511
987
  if (!resourceGroup.resources.empty()) {
512
988
  os << "\n";
513
989
  size_t i = 0;
990
+
514
991
  for (Collection<Resource>::const_iterator it = resourceGroup.resources.begin();
515
992
  it != resourceGroup.resources.end();
516
993
  ++i, ++it) {
@@ -536,11 +1013,63 @@ static void serialize(const ResourceGroup& resourceGroup, std::ostream &os)
536
1013
  }
537
1014
 
538
1015
  /**
539
- * \brief Serialize Resource Group into output stream.
540
- * \param resourceGroup Resource Groups to serialize.
541
- * \param os An output stream to serialize into.
1016
+ * \brief Serialize a source map of group of resources into output stream.
1017
+ * \param resourceGroup Source map of a group to serialize.
1018
+ * \brief os An output stream to serialize into.
542
1019
  */
543
- static void serialize(const Collection<ResourceGroup>::type& resourceGroups, std::ostream &os)
1020
+ static void serialize(const SourceMap<ResourceGroup>& resourceGroup, std::ostream &os)
1021
+ {
1022
+ indent(2, os);
1023
+ os << "{\n";
1024
+
1025
+ // Name
1026
+ serialize(SerializeKey::Name, resourceGroup.name, 3, false, os);
1027
+ os << NewLineItemBlock;
1028
+
1029
+ // Description
1030
+ serialize(SerializeKey::Description, resourceGroup.description, 3, false, os);
1031
+ os << NewLineItemBlock;
1032
+
1033
+ // Resources
1034
+ indent(3, os);
1035
+ serialize(SerializeKey::Resources, os);
1036
+ os << ": ";
1037
+ os << "[";
1038
+
1039
+ if (!resourceGroup.resources.collection.empty()) {
1040
+ os << "\n";
1041
+ size_t i = 0;
1042
+
1043
+ for (Collection<SourceMap<Resource> >::const_iterator it = resourceGroup.resources.collection.begin();
1044
+ it != resourceGroup.resources.collection.end();
1045
+ ++i, ++it) {
1046
+
1047
+ if (i > 0 && i < resourceGroup.resources.collection.size())
1048
+ os << NewLineItemBlock;
1049
+
1050
+ serialize(*it, os);
1051
+ }
1052
+
1053
+ if (!resourceGroup.resources.collection.empty()) {
1054
+ os << "\n";
1055
+ indent(3, os);
1056
+ }
1057
+ }
1058
+
1059
+ os << "]";
1060
+
1061
+ // Close the group
1062
+ os << "\n";
1063
+ indent(2, os);
1064
+ os << "}";
1065
+ }
1066
+
1067
+ /**
1068
+ * \brief Serialize Resource Groups into output stream.
1069
+ * \param resourceGroups Resource Groups to serialize.
1070
+ * \param os An output stream to serialize into.
1071
+ */
1072
+ static void serialize(const ResourceGroups& resourceGroups, std::ostream &os)
544
1073
  {
545
1074
  indent(1, os);
546
1075
  serialize(SerializeKey::ResourceGroups, os);
@@ -550,6 +1079,7 @@ static void serialize(const Collection<ResourceGroup>::type& resourceGroups, std
550
1079
  if (!resourceGroups.empty()) {
551
1080
  os << "\n";
552
1081
  size_t i = 0;
1082
+
553
1083
  for (Collection<ResourceGroup>::const_iterator it = resourceGroups.begin(); it != resourceGroups.end(); ++i, ++it) {
554
1084
 
555
1085
  if (i > 0 && i < resourceGroups.size())
@@ -565,6 +1095,37 @@ static void serialize(const Collection<ResourceGroup>::type& resourceGroups, std
565
1095
  os << "]";
566
1096
  }
567
1097
 
1098
+ /**
1099
+ * \brief Serialize Resource Groups source map into output stream.
1100
+ * \param resourceGroups Resource Groups source map to serialize.
1101
+ * \param os An output stream to serialize into.
1102
+ */
1103
+ static void serialize(const Collection<SourceMap<ResourceGroup> >::type& resourceGroups, std::ostream &os)
1104
+ {
1105
+ indent(1, os);
1106
+ serialize(SerializeKey::ResourceGroups, os);
1107
+ os << ": ";
1108
+ os << "[";
1109
+
1110
+ if (!resourceGroups.empty()) {
1111
+ os << "\n";
1112
+ size_t i = 0;
1113
+
1114
+ for (Collection<SourceMap<ResourceGroup> >::const_iterator it = resourceGroups.begin(); it != resourceGroups.end(); ++i, ++it) {
1115
+
1116
+ if (i > 0 && i < resourceGroups.size())
1117
+ os << NewLineItemBlock;
1118
+
1119
+ serialize(*it, os);
1120
+ }
1121
+
1122
+ os << "\n";
1123
+ indent(1, os);
1124
+ }
1125
+
1126
+ os << "]";
1127
+ }
1128
+
568
1129
  /**
569
1130
  * \brief Serialize a blueprint into output stream.
570
1131
  * \param blueprint The blueprint to serialize.
@@ -595,7 +1156,38 @@ static void serialize(const Blueprint& blueprint, std::ostream &os)
595
1156
  os << "\n}\n";
596
1157
  }
597
1158
 
1159
+ /**
1160
+ * \brief Serialize a blueprint source map into output stream.
1161
+ * \param blueprint The blueprint source map to serialize.
1162
+ * \param os An output stream to serialize into.
1163
+ */
1164
+ static void serialize(const SourceMap<Blueprint>& blueprint, std::ostream &os)
1165
+ {
1166
+ os << "{\n";
1167
+
1168
+ // Metadata
1169
+ serialize(blueprint.metadata.collection, os);
1170
+
1171
+ // Name
1172
+ serialize(SerializeKey::Name, blueprint.name, 1, false, os);
1173
+ os << NewLineItemBlock;
1174
+
1175
+ // Description
1176
+ serialize(SerializeKey::Description, blueprint.description, 1, false, os);
1177
+ os << NewLineItemBlock;
1178
+
1179
+ // Resource Groups
1180
+ serialize(blueprint.resourceGroups.collection, os);
1181
+
1182
+ os << "\n}\n";
1183
+ }
1184
+
598
1185
  void snowcrash::SerializeJSON(const snowcrash::Blueprint& blueprint, std::ostream &os)
599
1186
  {
600
1187
  serialize(blueprint, os);
601
1188
  }
1189
+
1190
+ void snowcrash::SerializeSourceMapJSON(const snowcrash::SourceMap<snowcrash::Blueprint>& blueprint, std::ostream &os)
1191
+ {
1192
+ serialize(blueprint, os);
1193
+ }