xref: /llvm-project/llvm/lib/Support/YAMLTraits.cpp (revision 4f26edd5e9eb3b6cea19e15ca8fb2c8416b82fa8)
1 //===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Support/YAMLTraits.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/Support/Casting.h"
16 #include "llvm/Support/Errc.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/LineIterator.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/VersionTuple.h"
22 #include "llvm/Support/YAMLParser.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <cassert>
25 #include <cstdint>
26 #include <cstring>
27 #include <string>
28 #include <vector>
29 
30 using namespace llvm;
31 using namespace yaml;
32 
33 //===----------------------------------------------------------------------===//
34 //  IO
35 //===----------------------------------------------------------------------===//
36 
37 IO::IO(void *Context) : Ctxt(Context) {}
38 
39 IO::~IO() = default;
40 
41 void *IO::getContext() const {
42   return Ctxt;
43 }
44 
45 void IO::setContext(void *Context) {
46   Ctxt = Context;
47 }
48 
49 void IO::setAllowUnknownKeys(bool Allow) {
50   llvm_unreachable("Only supported for Input");
51 }
52 
53 //===----------------------------------------------------------------------===//
54 //  Input
55 //===----------------------------------------------------------------------===//
56 
57 Input::Input(StringRef InputContent, void *Ctxt,
58              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
59     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
60   if (DiagHandler)
61     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
62   DocIterator = Strm->begin();
63 }
64 
65 Input::Input(MemoryBufferRef Input, void *Ctxt,
66              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
67     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
68   if (DiagHandler)
69     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
70   DocIterator = Strm->begin();
71 }
72 
73 Input::~Input() = default;
74 
75 std::error_code Input::error() { return EC; }
76 
77 bool Input::outputting() const {
78   return false;
79 }
80 
81 bool Input::setCurrentDocument() {
82   if (DocIterator != Strm->end()) {
83     Node *N = DocIterator->getRoot();
84     if (!N) {
85       EC = make_error_code(errc::invalid_argument);
86       return false;
87     }
88 
89     if (isa<NullNode>(N)) {
90       // Empty files are allowed and ignored
91       ++DocIterator;
92       return setCurrentDocument();
93     }
94     releaseHNodeBuffers();
95     TopNode = createHNodes(N);
96     CurrentNode = TopNode;
97     return true;
98   }
99   return false;
100 }
101 
102 bool Input::nextDocument() {
103   return ++DocIterator != Strm->end();
104 }
105 
106 const Node *Input::getCurrentNode() const {
107   return CurrentNode ? CurrentNode->_node : nullptr;
108 }
109 
110 bool Input::mapTag(StringRef Tag, bool Default) {
111   // CurrentNode can be null if setCurrentDocument() was unable to
112   // parse the document because it was invalid or empty.
113   if (!CurrentNode)
114     return false;
115 
116   std::string foundTag = CurrentNode->_node->getVerbatimTag();
117   if (foundTag.empty()) {
118     // If no tag found and 'Tag' is the default, say it was found.
119     return Default;
120   }
121   // Return true iff found tag matches supplied tag.
122   return Tag == foundTag;
123 }
124 
125 void Input::beginMapping() {
126   if (EC)
127     return;
128   // CurrentNode can be null if the document is empty.
129   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
130   if (MN) {
131     MN->ValidKeys.clear();
132   }
133 }
134 
135 std::vector<StringRef> Input::keys() {
136   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
137   std::vector<StringRef> Ret;
138   if (!MN) {
139     setError(CurrentNode, "not a mapping");
140     return Ret;
141   }
142   for (auto &P : MN->Mapping)
143     Ret.push_back(P.first());
144   return Ret;
145 }
146 
147 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
148                          void *&SaveInfo) {
149   UseDefault = false;
150   if (EC)
151     return false;
152 
153   // CurrentNode is null for empty documents, which is an error in case required
154   // nodes are present.
155   if (!CurrentNode) {
156     if (Required)
157       EC = make_error_code(errc::invalid_argument);
158     else
159       UseDefault = true;
160     return false;
161   }
162 
163   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
164   if (!MN) {
165     if (Required || !isa<EmptyHNode>(CurrentNode))
166       setError(CurrentNode, "not a mapping");
167     else
168       UseDefault = true;
169     return false;
170   }
171   MN->ValidKeys.push_back(Key);
172   HNode *Value = MN->Mapping[Key].first;
173   if (!Value) {
174     if (Required)
175       setError(CurrentNode, Twine("missing required key '") + Key + "'");
176     else
177       UseDefault = true;
178     return false;
179   }
180   SaveInfo = CurrentNode;
181   CurrentNode = Value;
182   return true;
183 }
184 
185 void Input::postflightKey(void *saveInfo) {
186   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
187 }
188 
189 void Input::endMapping() {
190   if (EC)
191     return;
192   // CurrentNode can be null if the document is empty.
193   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
194   if (!MN)
195     return;
196   for (const auto &NN : MN->Mapping) {
197     if (!is_contained(MN->ValidKeys, NN.first())) {
198       const SMRange &ReportLoc = NN.second.second;
199       if (!AllowUnknownKeys) {
200         setError(ReportLoc, Twine("unknown key '") + NN.first() + "'");
201         break;
202       } else
203         reportWarning(ReportLoc, Twine("unknown key '") + NN.first() + "'");
204     }
205   }
206 }
207 
208 void Input::beginFlowMapping() { beginMapping(); }
209 
210 void Input::endFlowMapping() { endMapping(); }
211 
212 unsigned Input::beginSequence() {
213   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
214     return SQ->Entries.size();
215   if (isa<EmptyHNode>(CurrentNode))
216     return 0;
217   // Treat case where there's a scalar "null" value as an empty sequence.
218   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
219     if (isNull(SN->value()))
220       return 0;
221   }
222   // Any other type of HNode is an error.
223   setError(CurrentNode, "not a sequence");
224   return 0;
225 }
226 
227 void Input::endSequence() {
228 }
229 
230 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
231   if (EC)
232     return false;
233   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
234     SaveInfo = CurrentNode;
235     CurrentNode = SQ->Entries[Index];
236     return true;
237   }
238   return false;
239 }
240 
241 void Input::postflightElement(void *SaveInfo) {
242   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
243 }
244 
245 unsigned Input::beginFlowSequence() { return beginSequence(); }
246 
247 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
248   if (EC)
249     return false;
250   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
251     SaveInfo = CurrentNode;
252     CurrentNode = SQ->Entries[index];
253     return true;
254   }
255   return false;
256 }
257 
258 void Input::postflightFlowElement(void *SaveInfo) {
259   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
260 }
261 
262 void Input::endFlowSequence() {
263 }
264 
265 void Input::beginEnumScalar() {
266   ScalarMatchFound = false;
267 }
268 
269 bool Input::matchEnumScalar(const char *Str, bool) {
270   if (ScalarMatchFound)
271     return false;
272   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
273     if (SN->value() == Str) {
274       ScalarMatchFound = true;
275       return true;
276     }
277   }
278   return false;
279 }
280 
281 bool Input::matchEnumFallback() {
282   if (ScalarMatchFound)
283     return false;
284   ScalarMatchFound = true;
285   return true;
286 }
287 
288 void Input::endEnumScalar() {
289   if (!ScalarMatchFound) {
290     setError(CurrentNode, "unknown enumerated scalar");
291   }
292 }
293 
294 bool Input::beginBitSetScalar(bool &DoClear) {
295   BitValuesUsed.clear();
296   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
297     BitValuesUsed.resize(SQ->Entries.size());
298   } else {
299     setError(CurrentNode, "expected sequence of bit values");
300   }
301   DoClear = true;
302   return true;
303 }
304 
305 bool Input::bitSetMatch(const char *Str, bool) {
306   if (EC)
307     return false;
308   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
309     unsigned Index = 0;
310     for (auto &N : SQ->Entries) {
311       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N)) {
312         if (SN->value() == Str) {
313           BitValuesUsed[Index] = true;
314           return true;
315         }
316       } else {
317         setError(CurrentNode, "unexpected scalar in sequence of bit values");
318       }
319       ++Index;
320     }
321   } else {
322     setError(CurrentNode, "expected sequence of bit values");
323   }
324   return false;
325 }
326 
327 void Input::endBitSetScalar() {
328   if (EC)
329     return;
330   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
331     assert(BitValuesUsed.size() == SQ->Entries.size());
332     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
333       if (!BitValuesUsed[i]) {
334         setError(SQ->Entries[i], "unknown bit value");
335         return;
336       }
337     }
338   }
339 }
340 
341 void Input::scalarString(StringRef &S, QuotingType) {
342   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
343     S = SN->value();
344   } else {
345     setError(CurrentNode, "unexpected scalar");
346   }
347 }
348 
349 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
350 
351 void Input::scalarTag(std::string &Tag) {
352   Tag = CurrentNode->_node->getVerbatimTag();
353 }
354 
355 void Input::setError(HNode *hnode, const Twine &message) {
356   assert(hnode && "HNode must not be NULL");
357   setError(hnode->_node, message);
358 }
359 
360 NodeKind Input::getNodeKind() {
361   if (isa<ScalarHNode>(CurrentNode))
362     return NodeKind::Scalar;
363   else if (isa<MapHNode>(CurrentNode))
364     return NodeKind::Map;
365   else if (isa<SequenceHNode>(CurrentNode))
366     return NodeKind::Sequence;
367   llvm_unreachable("Unsupported node kind");
368 }
369 
370 void Input::setError(Node *node, const Twine &message) {
371   Strm->printError(node, message);
372   EC = make_error_code(errc::invalid_argument);
373 }
374 
375 void Input::setError(const SMRange &range, const Twine &message) {
376   Strm->printError(range, message);
377   EC = make_error_code(errc::invalid_argument);
378 }
379 
380 void Input::reportWarning(HNode *hnode, const Twine &message) {
381   assert(hnode && "HNode must not be NULL");
382   Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
383 }
384 
385 void Input::reportWarning(Node *node, const Twine &message) {
386   Strm->printError(node, message, SourceMgr::DK_Warning);
387 }
388 
389 void Input::reportWarning(const SMRange &range, const Twine &message) {
390   Strm->printError(range, message, SourceMgr::DK_Warning);
391 }
392 
393 void Input::releaseHNodeBuffers() {
394   EmptyHNodeAllocator.DestroyAll();
395   ScalarHNodeAllocator.DestroyAll();
396   SequenceHNodeAllocator.DestroyAll();
397   MapHNodeAllocator.DestroyAll();
398 }
399 
400 Input::HNode *Input::createHNodes(Node *N) {
401   SmallString<128> StringStorage;
402   switch (N->getType()) {
403   case Node::NK_Scalar: {
404     ScalarNode *SN = dyn_cast<ScalarNode>(N);
405     StringRef KeyStr = SN->getValue(StringStorage);
406     if (!StringStorage.empty()) {
407       // Copy string to permanent storage
408       KeyStr = StringStorage.str().copy(StringAllocator);
409     }
410     return new (ScalarHNodeAllocator.Allocate()) ScalarHNode(N, KeyStr);
411   }
412   case Node::NK_BlockScalar: {
413     BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N);
414     StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
415     return new (ScalarHNodeAllocator.Allocate()) ScalarHNode(N, ValueCopy);
416   }
417   case Node::NK_Sequence: {
418     SequenceNode *SQ = dyn_cast<SequenceNode>(N);
419     auto SQHNode = new (SequenceHNodeAllocator.Allocate()) SequenceHNode(N);
420     for (Node &SN : *SQ) {
421       auto Entry = createHNodes(&SN);
422       if (EC)
423         break;
424       SQHNode->Entries.push_back(Entry);
425     }
426     return SQHNode;
427   }
428   case Node::NK_Mapping: {
429     MappingNode *Map = dyn_cast<MappingNode>(N);
430     auto mapHNode = new (MapHNodeAllocator.Allocate()) MapHNode(N);
431     for (KeyValueNode &KVN : *Map) {
432       Node *KeyNode = KVN.getKey();
433       ScalarNode *Key = dyn_cast_or_null<ScalarNode>(KeyNode);
434       Node *Value = KVN.getValue();
435       if (!Key || !Value) {
436         if (!Key)
437           setError(KeyNode, "Map key must be a scalar");
438         if (!Value)
439           setError(KeyNode, "Map value must not be empty");
440         break;
441       }
442       StringStorage.clear();
443       StringRef KeyStr = Key->getValue(StringStorage);
444       if (!StringStorage.empty()) {
445         // Copy string to permanent storage
446         KeyStr = StringStorage.str().copy(StringAllocator);
447       }
448       if (mapHNode->Mapping.count(KeyStr))
449         // From YAML spec: "The content of a mapping node is an unordered set of
450         // key/value node pairs, with the restriction that each of the keys is
451         // unique."
452         setError(KeyNode, Twine("duplicated mapping key '") + KeyStr + "'");
453       auto ValueHNode = createHNodes(Value);
454       if (EC)
455         break;
456       mapHNode->Mapping[KeyStr] =
457           std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
458     }
459     return std::move(mapHNode);
460   }
461   case Node::NK_Null:
462     return new (EmptyHNodeAllocator.Allocate()) EmptyHNode(N);
463   default:
464     setError(N, "unknown node kind");
465     return nullptr;
466   }
467 }
468 
469 void Input::setError(const Twine &Message) {
470   setError(CurrentNode, Message);
471 }
472 
473 void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
474 
475 bool Input::canElideEmptySequence() {
476   return false;
477 }
478 
479 //===----------------------------------------------------------------------===//
480 //  Output
481 //===----------------------------------------------------------------------===//
482 
483 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
484     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
485 
486 Output::~Output() = default;
487 
488 bool Output::outputting() const {
489   return true;
490 }
491 
492 void Output::beginMapping() {
493   StateStack.push_back(inMapFirstKey);
494   PaddingBeforeContainer = Padding;
495   Padding = "\n";
496 }
497 
498 bool Output::mapTag(StringRef Tag, bool Use) {
499   if (Use) {
500     // If this tag is being written inside a sequence we should write the start
501     // of the sequence before writing the tag, otherwise the tag won't be
502     // attached to the element in the sequence, but rather the sequence itself.
503     bool SequenceElement = false;
504     if (StateStack.size() > 1) {
505       auto &E = StateStack[StateStack.size() - 2];
506       SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
507     }
508     if (SequenceElement && StateStack.back() == inMapFirstKey) {
509       newLineCheck();
510     } else {
511       output(" ");
512     }
513     output(Tag);
514     if (SequenceElement) {
515       // If we're writing the tag during the first element of a map, the tag
516       // takes the place of the first element in the sequence.
517       if (StateStack.back() == inMapFirstKey) {
518         StateStack.pop_back();
519         StateStack.push_back(inMapOtherKey);
520       }
521       // Tags inside maps in sequences should act as keys in the map from a
522       // formatting perspective, so we always want a newline in a sequence.
523       Padding = "\n";
524     }
525   }
526   return Use;
527 }
528 
529 void Output::endMapping() {
530   // If we did not map anything, we should explicitly emit an empty map
531   if (StateStack.back() == inMapFirstKey) {
532     Padding = PaddingBeforeContainer;
533     newLineCheck();
534     output("{}");
535     Padding = "\n";
536   }
537   StateStack.pop_back();
538 }
539 
540 std::vector<StringRef> Output::keys() {
541   report_fatal_error("invalid call");
542 }
543 
544 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
545                           bool &UseDefault, void *&SaveInfo) {
546   UseDefault = false;
547   SaveInfo = nullptr;
548   if (Required || !SameAsDefault || WriteDefaultValues) {
549     auto State = StateStack.back();
550     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
551       flowKey(Key);
552     } else {
553       newLineCheck();
554       paddedKey(Key);
555     }
556     return true;
557   }
558   return false;
559 }
560 
561 void Output::postflightKey(void *) {
562   if (StateStack.back() == inMapFirstKey) {
563     StateStack.pop_back();
564     StateStack.push_back(inMapOtherKey);
565   } else if (StateStack.back() == inFlowMapFirstKey) {
566     StateStack.pop_back();
567     StateStack.push_back(inFlowMapOtherKey);
568   }
569 }
570 
571 void Output::beginFlowMapping() {
572   StateStack.push_back(inFlowMapFirstKey);
573   newLineCheck();
574   ColumnAtMapFlowStart = Column;
575   output("{ ");
576 }
577 
578 void Output::endFlowMapping() {
579   StateStack.pop_back();
580   outputUpToEndOfLine(" }");
581 }
582 
583 void Output::beginDocuments() {
584   outputUpToEndOfLine("---");
585 }
586 
587 bool Output::preflightDocument(unsigned index) {
588   if (index > 0)
589     outputUpToEndOfLine("\n---");
590   return true;
591 }
592 
593 void Output::postflightDocument() {
594 }
595 
596 void Output::endDocuments() {
597   output("\n...\n");
598 }
599 
600 unsigned Output::beginSequence() {
601   StateStack.push_back(inSeqFirstElement);
602   PaddingBeforeContainer = Padding;
603   Padding = "\n";
604   return 0;
605 }
606 
607 void Output::endSequence() {
608   // If we did not emit anything, we should explicitly emit an empty sequence
609   if (StateStack.back() == inSeqFirstElement) {
610     Padding = PaddingBeforeContainer;
611     newLineCheck(/*EmptySequence=*/true);
612     output("[]");
613     Padding = "\n";
614   }
615   StateStack.pop_back();
616 }
617 
618 bool Output::preflightElement(unsigned, void *&SaveInfo) {
619   SaveInfo = nullptr;
620   return true;
621 }
622 
623 void Output::postflightElement(void *) {
624   if (StateStack.back() == inSeqFirstElement) {
625     StateStack.pop_back();
626     StateStack.push_back(inSeqOtherElement);
627   } else if (StateStack.back() == inFlowSeqFirstElement) {
628     StateStack.pop_back();
629     StateStack.push_back(inFlowSeqOtherElement);
630   }
631 }
632 
633 unsigned Output::beginFlowSequence() {
634   StateStack.push_back(inFlowSeqFirstElement);
635   newLineCheck();
636   ColumnAtFlowStart = Column;
637   output("[ ");
638   NeedFlowSequenceComma = false;
639   return 0;
640 }
641 
642 void Output::endFlowSequence() {
643   StateStack.pop_back();
644   outputUpToEndOfLine(" ]");
645 }
646 
647 bool Output::preflightFlowElement(unsigned, void *&SaveInfo) {
648   if (NeedFlowSequenceComma)
649     output(", ");
650   if (WrapColumn && Column > WrapColumn) {
651     output("\n");
652     for (int i = 0; i < ColumnAtFlowStart; ++i)
653       output(" ");
654     Column = ColumnAtFlowStart;
655     output("  ");
656   }
657   SaveInfo = nullptr;
658   return true;
659 }
660 
661 void Output::postflightFlowElement(void *) {
662   NeedFlowSequenceComma = true;
663 }
664 
665 void Output::beginEnumScalar() {
666   EnumerationMatchFound = false;
667 }
668 
669 bool Output::matchEnumScalar(const char *Str, bool Match) {
670   if (Match && !EnumerationMatchFound) {
671     newLineCheck();
672     outputUpToEndOfLine(Str);
673     EnumerationMatchFound = true;
674   }
675   return false;
676 }
677 
678 bool Output::matchEnumFallback() {
679   if (EnumerationMatchFound)
680     return false;
681   EnumerationMatchFound = true;
682   return true;
683 }
684 
685 void Output::endEnumScalar() {
686   if (!EnumerationMatchFound)
687     llvm_unreachable("bad runtime enum value");
688 }
689 
690 bool Output::beginBitSetScalar(bool &DoClear) {
691   newLineCheck();
692   output("[ ");
693   NeedBitValueComma = false;
694   DoClear = false;
695   return true;
696 }
697 
698 bool Output::bitSetMatch(const char *Str, bool Matches) {
699   if (Matches) {
700     if (NeedBitValueComma)
701       output(", ");
702     output(Str);
703     NeedBitValueComma = true;
704   }
705   return false;
706 }
707 
708 void Output::endBitSetScalar() {
709   outputUpToEndOfLine(" ]");
710 }
711 
712 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
713   newLineCheck();
714   if (S.empty()) {
715     // Print '' for the empty string because leaving the field empty is not
716     // allowed.
717     outputUpToEndOfLine("''");
718     return;
719   }
720   output(S, MustQuote);
721   outputUpToEndOfLine("");
722 }
723 
724 void Output::blockScalarString(StringRef &S) {
725   if (!StateStack.empty())
726     newLineCheck();
727   output(" |");
728   outputNewLine();
729 
730   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
731 
732   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
733   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
734     for (unsigned I = 0; I < Indent; ++I) {
735       output("  ");
736     }
737     output(*Lines);
738     outputNewLine();
739   }
740 }
741 
742 void Output::scalarTag(std::string &Tag) {
743   if (Tag.empty())
744     return;
745   newLineCheck();
746   output(Tag);
747   output(" ");
748 }
749 
750 void Output::setError(const Twine &message) {
751 }
752 
753 std::error_code Output::error() { return {}; }
754 
755 bool Output::canElideEmptySequence() {
756   // Normally, with an optional key/value where the value is an empty sequence,
757   // the whole key/value can be not written.  But, that produces wrong yaml
758   // if the key/value is the only thing in the map and the map is used in
759   // a sequence.  This detects if the this sequence is the first key/value
760   // in map that itself is embedded in a sequence.
761   if (StateStack.size() < 2)
762     return true;
763   if (StateStack.back() != inMapFirstKey)
764     return true;
765   return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
766 }
767 
768 void Output::output(StringRef s) {
769   Column += s.size();
770   Out << s;
771 }
772 
773 void Output::output(StringRef S, QuotingType MustQuote) {
774   if (MustQuote == QuotingType::None) {
775     // Only quote if we must.
776     output(S);
777     return;
778   }
779 
780   StringLiteral Quote = MustQuote == QuotingType::Single ? StringLiteral("'")
781                                                          : StringLiteral("\"");
782   output(Quote); // Starting quote.
783 
784   // When using double-quoted strings (and only in that case), non-printable
785   // characters may be present, and will be escaped using a variety of
786   // unicode-scalar and special short-form escapes. This is handled in
787   // yaml::escape.
788   if (MustQuote == QuotingType::Double) {
789     output(yaml::escape(S, /* EscapePrintable= */ false));
790     output(Quote);
791     return;
792   }
793 
794   unsigned i = 0;
795   unsigned j = 0;
796   unsigned End = S.size();
797   const char *Base = S.data();
798 
799   // When using single-quoted strings, any single quote ' must be doubled to be
800   // escaped.
801   while (j < End) {
802     if (S[j] == '\'') {                   // Escape quotes.
803       output(StringRef(&Base[i], j - i)); // "flush".
804       output(StringLiteral("''"));        // Print it as ''
805       i = j + 1;
806     }
807     ++j;
808   }
809   output(StringRef(&Base[i], j - i));
810   output(Quote); // Ending quote.
811 }
812 
813 void Output::outputUpToEndOfLine(StringRef s) {
814   output(s);
815   if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
816                              !inFlowMapAnyKey(StateStack.back())))
817     Padding = "\n";
818 }
819 
820 void Output::outputNewLine() {
821   Out << "\n";
822   Column = 0;
823 }
824 
825 // if seq at top, indent as if map, then add "- "
826 // if seq in middle, use "- " if firstKey, else use "  "
827 //
828 
829 void Output::newLineCheck(bool EmptySequence) {
830   if (Padding != "\n") {
831     output(Padding);
832     Padding = {};
833     return;
834   }
835   outputNewLine();
836   Padding = {};
837 
838   if (StateStack.size() == 0 || EmptySequence)
839     return;
840 
841   unsigned Indent = StateStack.size() - 1;
842   bool PossiblyNestedSeq = false;
843   auto I = StateStack.rbegin(), E = StateStack.rend();
844 
845   if (inSeqAnyElement(*I)) {
846     PossiblyNestedSeq = true; // Not possibly but always.
847     ++Indent;
848   } else if (*I == inMapFirstKey || *I == inFlowMapFirstKey ||
849              inFlowSeqAnyElement(*I)) {
850     PossiblyNestedSeq = true;
851     ++I; // Skip back().
852   }
853 
854   unsigned OutputDashCount = 0;
855   if (PossiblyNestedSeq) {
856     // Count up consecutive inSeqFirstElement from the end, unless
857     // inSeqFirstElement is the top of nested sequence.
858     while (I != E) {
859       // Don't count the top of nested sequence.
860       if (!inSeqAnyElement(*I))
861         break;
862 
863       ++OutputDashCount;
864 
865       // Stop counting if consecutive inSeqFirstElement ends.
866       if (*I++ != inSeqFirstElement)
867         break;
868     }
869   }
870 
871   for (unsigned I = OutputDashCount; I < Indent; ++I)
872     output("  ");
873 
874   for (unsigned I = 0; I < OutputDashCount; ++I)
875     output("- ");
876 }
877 
878 void Output::paddedKey(StringRef key) {
879   output(key, needsQuotes(key, false));
880   output(":");
881   const char *spaces = "                ";
882   if (key.size() < strlen(spaces))
883     Padding = &spaces[key.size()];
884   else
885     Padding = " ";
886 }
887 
888 void Output::flowKey(StringRef Key) {
889   if (StateStack.back() == inFlowMapOtherKey)
890     output(", ");
891   if (WrapColumn && Column > WrapColumn) {
892     output("\n");
893     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
894       output(" ");
895     Column = ColumnAtMapFlowStart;
896     output("  ");
897   }
898   output(Key, needsQuotes(Key, false));
899   output(": ");
900 }
901 
902 NodeKind Output::getNodeKind() { report_fatal_error("invalid call"); }
903 
904 bool Output::inSeqAnyElement(InState State) {
905   return State == inSeqFirstElement || State == inSeqOtherElement;
906 }
907 
908 bool Output::inFlowSeqAnyElement(InState State) {
909   return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
910 }
911 
912 bool Output::inMapAnyKey(InState State) {
913   return State == inMapFirstKey || State == inMapOtherKey;
914 }
915 
916 bool Output::inFlowMapAnyKey(InState State) {
917   return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
918 }
919 
920 //===----------------------------------------------------------------------===//
921 //  traits for built-in types
922 //===----------------------------------------------------------------------===//
923 
924 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
925   Out << (Val ? "true" : "false");
926 }
927 
928 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
929   if (std::optional<bool> Parsed = parseBool(Scalar)) {
930     Val = *Parsed;
931     return StringRef();
932   }
933   return "invalid boolean";
934 }
935 
936 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
937                                      raw_ostream &Out) {
938   Out << Val;
939 }
940 
941 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
942                                          StringRef &Val) {
943   Val = Scalar;
944   return StringRef();
945 }
946 
947 void ScalarTraits<std::string>::output(const std::string &Val, void *,
948                                        raw_ostream &Out) {
949   Out << Val;
950 }
951 
952 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
953                                            std::string &Val) {
954   Val = Scalar.str();
955   return StringRef();
956 }
957 
958 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
959                                    raw_ostream &Out) {
960   // use temp uin32_t because ostream thinks uint8_t is a character
961   uint32_t Num = Val;
962   Out << Num;
963 }
964 
965 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
966   unsigned long long n;
967   if (getAsUnsignedInteger(Scalar, 0, n))
968     return "invalid number";
969   if (n > 0xFF)
970     return "out of range number";
971   Val = n;
972   return StringRef();
973 }
974 
975 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
976                                     raw_ostream &Out) {
977   Out << Val;
978 }
979 
980 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
981                                         uint16_t &Val) {
982   unsigned long long n;
983   if (getAsUnsignedInteger(Scalar, 0, n))
984     return "invalid number";
985   if (n > 0xFFFF)
986     return "out of range number";
987   Val = n;
988   return StringRef();
989 }
990 
991 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
992                                     raw_ostream &Out) {
993   Out << Val;
994 }
995 
996 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
997                                         uint32_t &Val) {
998   unsigned long long n;
999   if (getAsUnsignedInteger(Scalar, 0, n))
1000     return "invalid number";
1001   if (n > 0xFFFFFFFFUL)
1002     return "out of range number";
1003   Val = n;
1004   return StringRef();
1005 }
1006 
1007 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
1008                                     raw_ostream &Out) {
1009   Out << Val;
1010 }
1011 
1012 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
1013                                         uint64_t &Val) {
1014   unsigned long long N;
1015   if (getAsUnsignedInteger(Scalar, 0, N))
1016     return "invalid number";
1017   Val = N;
1018   return StringRef();
1019 }
1020 
1021 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
1022   // use temp in32_t because ostream thinks int8_t is a character
1023   int32_t Num = Val;
1024   Out << Num;
1025 }
1026 
1027 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
1028   long long N;
1029   if (getAsSignedInteger(Scalar, 0, N))
1030     return "invalid number";
1031   if ((N > 127) || (N < -128))
1032     return "out of range number";
1033   Val = N;
1034   return StringRef();
1035 }
1036 
1037 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
1038                                    raw_ostream &Out) {
1039   Out << Val;
1040 }
1041 
1042 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
1043   long long N;
1044   if (getAsSignedInteger(Scalar, 0, N))
1045     return "invalid number";
1046   if ((N > INT16_MAX) || (N < INT16_MIN))
1047     return "out of range number";
1048   Val = N;
1049   return StringRef();
1050 }
1051 
1052 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
1053                                    raw_ostream &Out) {
1054   Out << Val;
1055 }
1056 
1057 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
1058   long long N;
1059   if (getAsSignedInteger(Scalar, 0, N))
1060     return "invalid number";
1061   if ((N > INT32_MAX) || (N < INT32_MIN))
1062     return "out of range number";
1063   Val = N;
1064   return StringRef();
1065 }
1066 
1067 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
1068                                    raw_ostream &Out) {
1069   Out << Val;
1070 }
1071 
1072 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
1073   long long N;
1074   if (getAsSignedInteger(Scalar, 0, N))
1075     return "invalid number";
1076   Val = N;
1077   return StringRef();
1078 }
1079 
1080 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
1081   Out << format("%g", Val);
1082 }
1083 
1084 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
1085   if (to_float(Scalar, Val))
1086     return StringRef();
1087   return "invalid floating point number";
1088 }
1089 
1090 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
1091   Out << format("%g", Val);
1092 }
1093 
1094 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
1095   if (to_float(Scalar, Val))
1096     return StringRef();
1097   return "invalid floating point number";
1098 }
1099 
1100 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
1101   Out << format("0x%" PRIX8, (uint8_t)Val);
1102 }
1103 
1104 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
1105   unsigned long long n;
1106   if (getAsUnsignedInteger(Scalar, 0, n))
1107     return "invalid hex8 number";
1108   if (n > 0xFF)
1109     return "out of range hex8 number";
1110   Val = n;
1111   return StringRef();
1112 }
1113 
1114 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
1115   Out << format("0x%" PRIX16, (uint16_t)Val);
1116 }
1117 
1118 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
1119   unsigned long long n;
1120   if (getAsUnsignedInteger(Scalar, 0, n))
1121     return "invalid hex16 number";
1122   if (n > 0xFFFF)
1123     return "out of range hex16 number";
1124   Val = n;
1125   return StringRef();
1126 }
1127 
1128 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1129   Out << format("0x%" PRIX32, (uint32_t)Val);
1130 }
1131 
1132 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1133   unsigned long long n;
1134   if (getAsUnsignedInteger(Scalar, 0, n))
1135     return "invalid hex32 number";
1136   if (n > 0xFFFFFFFFUL)
1137     return "out of range hex32 number";
1138   Val = n;
1139   return StringRef();
1140 }
1141 
1142 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1143   Out << format("0x%" PRIX64, (uint64_t)Val);
1144 }
1145 
1146 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1147   unsigned long long Num;
1148   if (getAsUnsignedInteger(Scalar, 0, Num))
1149     return "invalid hex64 number";
1150   Val = Num;
1151   return StringRef();
1152 }
1153 
1154 void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
1155                                         llvm::raw_ostream &Out) {
1156   Out << Val.getAsString();
1157 }
1158 
1159 StringRef ScalarTraits<VersionTuple>::input(StringRef Scalar, void *,
1160                                             VersionTuple &Val) {
1161   if (Val.tryParse(Scalar))
1162     return "invalid version format";
1163   return StringRef();
1164 }
1165