1 //===--- Format.cpp - Format C++ code -------------------------------------===//
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 /// \file
10 /// This file implements functions declared in Format.h. This will be
11 /// split into separate files as we go.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Format/Format.h"
16 #include "AffectedRangeManager.h"
17 #include "BreakableToken.h"
18 #include "ContinuationIndenter.h"
19 #include "DefinitionBlockSeparator.h"
20 #include "FormatInternal.h"
21 #include "FormatToken.h"
22 #include "FormatTokenLexer.h"
23 #include "NamespaceEndCommentsFixer.h"
24 #include "QualifierAlignmentFixer.h"
25 #include "SortJavaScriptImports.h"
26 #include "TokenAnalyzer.h"
27 #include "TokenAnnotator.h"
28 #include "UnwrappedLineFormatter.h"
29 #include "UnwrappedLineParser.h"
30 #include "UsingDeclarationsSorter.h"
31 #include "WhitespaceManager.h"
32 #include "clang/Basic/Diagnostic.h"
33 #include "clang/Basic/DiagnosticOptions.h"
34 #include "clang/Basic/SourceManager.h"
35 #include "clang/Lex/Lexer.h"
36 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/Sequence.h"
39 #include "llvm/ADT/StringRef.h"
40 #include "llvm/Support/Allocator.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/Path.h"
43 #include "llvm/Support/Regex.h"
44 #include "llvm/Support/VirtualFileSystem.h"
45 #include "llvm/Support/YAMLTraits.h"
46 #include <algorithm>
47 #include <memory>
48 #include <mutex>
49 #include <string>
50 #include <unordered_map>
51 
52 #define DEBUG_TYPE "format-formatter"
53 
54 using clang::format::FormatStyle;
55 
56 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat)
57 
58 namespace llvm {
59 namespace yaml {
60 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
61   static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
62     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
63     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
64     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
65     IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
66     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
67     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
68     IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
69     IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
70     IO.enumCase(Value, "Json", FormatStyle::LK_Json);
71   }
72 };
73 
74 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
75   static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
76     IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);
77     IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias
78     IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias
79 
80     IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);
81     IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias
82 
83     IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);
84     IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);
85     IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);
86 
87     IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);
88     IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias
89     IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
90   }
91 };
92 
93 template <>
94 struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> {
95   static void enumeration(IO &IO,
96                           FormatStyle::LambdaBodyIndentationKind &Value) {
97     IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature);
98     IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope);
99   }
100 };
101 
102 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
103   static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
104     IO.enumCase(Value, "Never", FormatStyle::UT_Never);
105     IO.enumCase(Value, "false", FormatStyle::UT_Never);
106     IO.enumCase(Value, "Always", FormatStyle::UT_Always);
107     IO.enumCase(Value, "true", FormatStyle::UT_Always);
108     IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
109     IO.enumCase(Value, "ForContinuationAndIndentation",
110                 FormatStyle::UT_ForContinuationAndIndentation);
111     IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
112   }
113 };
114 
115 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
116   static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
117     IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
118     IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
119     IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
120   }
121 };
122 
123 template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
124   static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) {
125     IO.enumCase(Value, "Never", FormatStyle::SBS_Never);
126     IO.enumCase(Value, "false", FormatStyle::SBS_Never);
127     IO.enumCase(Value, "Always", FormatStyle::SBS_Always);
128     IO.enumCase(Value, "true", FormatStyle::SBS_Always);
129     IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);
130   }
131 };
132 
133 template <>
134 struct ScalarEnumerationTraits<FormatStyle::QualifierAlignmentStyle> {
135   static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value) {
136     IO.enumCase(Value, "Leave", FormatStyle::QAS_Leave);
137     IO.enumCase(Value, "Left", FormatStyle::QAS_Left);
138     IO.enumCase(Value, "Right", FormatStyle::QAS_Right);
139     IO.enumCase(Value, "Custom", FormatStyle::QAS_Custom);
140   }
141 };
142 
143 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
144   static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
145     IO.enumCase(Value, "None", FormatStyle::SFS_None);
146     IO.enumCase(Value, "false", FormatStyle::SFS_None);
147     IO.enumCase(Value, "All", FormatStyle::SFS_All);
148     IO.enumCase(Value, "true", FormatStyle::SFS_All);
149     IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
150     IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
151     IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
152   }
153 };
154 
155 template <> struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveStyle> {
156   static void enumeration(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
157     IO.enumCase(Value, "None", FormatStyle::ACS_None);
158     IO.enumCase(Value, "Consecutive", FormatStyle::ACS_Consecutive);
159     IO.enumCase(Value, "AcrossEmptyLines", FormatStyle::ACS_AcrossEmptyLines);
160     IO.enumCase(Value, "AcrossComments", FormatStyle::ACS_AcrossComments);
161     IO.enumCase(Value, "AcrossEmptyLinesAndComments",
162                 FormatStyle::ACS_AcrossEmptyLinesAndComments);
163 
164     // For backward compatibility.
165     IO.enumCase(Value, "true", FormatStyle::ACS_Consecutive);
166     IO.enumCase(Value, "false", FormatStyle::ACS_None);
167   }
168 };
169 
170 template <>
171 struct ScalarEnumerationTraits<FormatStyle::ArrayInitializerAlignmentStyle> {
172   static void enumeration(IO &IO,
173                           FormatStyle::ArrayInitializerAlignmentStyle &Value) {
174     IO.enumCase(Value, "None", FormatStyle::AIAS_None);
175     IO.enumCase(Value, "Left", FormatStyle::AIAS_Left);
176     IO.enumCase(Value, "Right", FormatStyle::AIAS_Right);
177   }
178 };
179 
180 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
181   static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
182     IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
183     IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
184     IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
185     IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
186 
187     // For backward compatibility.
188     IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
189     IO.enumCase(Value, "false", FormatStyle::SIS_Never);
190     IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
191   }
192 };
193 
194 template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
195   static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) {
196     IO.enumCase(Value, "None", FormatStyle::SLS_None);
197     IO.enumCase(Value, "false", FormatStyle::SLS_None);
198     IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
199     IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
200     IO.enumCase(Value, "All", FormatStyle::SLS_All);
201     IO.enumCase(Value, "true", FormatStyle::SLS_All);
202   }
203 };
204 
205 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
206   static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
207     IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
208     IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
209     IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
210   }
211 };
212 
213 template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {
214   static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {
215     IO.enumCase(Value, "None", FormatStyle::TCS_None);
216     IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);
217   }
218 };
219 
220 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {
221   static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {
222     IO.enumCase(Value, "All", FormatStyle::BOS_All);
223     IO.enumCase(Value, "true", FormatStyle::BOS_All);
224     IO.enumCase(Value, "None", FormatStyle::BOS_None);
225     IO.enumCase(Value, "false", FormatStyle::BOS_None);
226     IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);
227   }
228 };
229 
230 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
231   static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
232     IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
233     IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
234     IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
235     IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
236     IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
237     IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
238     IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
239     IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
240     IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
241   }
242 };
243 
244 template <>
245 struct ScalarEnumerationTraits<
246     FormatStyle::BraceWrappingAfterControlStatementStyle> {
247   static void
248   enumeration(IO &IO,
249               FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {
250     IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);
251     IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);
252     IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
253 
254     // For backward compatibility.
255     IO.enumCase(Value, "false", FormatStyle::BWACS_Never);
256     IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
257   }
258 };
259 
260 template <>
261 struct ScalarEnumerationTraits<
262     FormatStyle::BreakBeforeConceptDeclarationsStyle> {
263   static void
264   enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value) {
265     IO.enumCase(Value, "Never", FormatStyle::BBCDS_Never);
266     IO.enumCase(Value, "Allowed", FormatStyle::BBCDS_Allowed);
267     IO.enumCase(Value, "Always", FormatStyle::BBCDS_Always);
268 
269     // For backward compatibility.
270     IO.enumCase(Value, "true", FormatStyle::BBCDS_Always);
271     IO.enumCase(Value, "false", FormatStyle::BBCDS_Allowed);
272   }
273 };
274 
275 template <>
276 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
277   static void
278   enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
279     IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
280     IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
281     IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
282   }
283 };
284 
285 template <>
286 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
287   static void enumeration(IO &IO,
288                           FormatStyle::BreakInheritanceListStyle &Value) {
289     IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
290     IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
291     IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
292     IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
293   }
294 };
295 
296 template <>
297 struct ScalarEnumerationTraits<FormatStyle::PackConstructorInitializersStyle> {
298   static void
299   enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value) {
300     IO.enumCase(Value, "Never", FormatStyle::PCIS_Never);
301     IO.enumCase(Value, "BinPack", FormatStyle::PCIS_BinPack);
302     IO.enumCase(Value, "CurrentLine", FormatStyle::PCIS_CurrentLine);
303     IO.enumCase(Value, "NextLine", FormatStyle::PCIS_NextLine);
304   }
305 };
306 
307 template <>
308 struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
309   static void
310   enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
311     IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
312     IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
313     IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
314   }
315 };
316 
317 template <>
318 struct ScalarEnumerationTraits<
319     FormatStyle::EmptyLineBeforeAccessModifierStyle> {
320   static void
321   enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
322     IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
323     IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
324     IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
325     IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
326   }
327 };
328 
329 template <>
330 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
331   static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
332     IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
333     IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
334     IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
335   }
336 };
337 
338 template <>
339 struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
340   static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
341     IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
342     IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
343     IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
344     IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
345     IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
346   }
347 };
348 
349 template <>
350 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
351   static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
352     IO.enumCase(Value, "None", FormatStyle::RTBS_None);
353     IO.enumCase(Value, "All", FormatStyle::RTBS_All);
354     IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
355     IO.enumCase(Value, "TopLevelDefinitions",
356                 FormatStyle::RTBS_TopLevelDefinitions);
357     IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
358   }
359 };
360 
361 template <>
362 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
363   static void enumeration(IO &IO,
364                           FormatStyle::BreakTemplateDeclarationsStyle &Value) {
365     IO.enumCase(Value, "No", FormatStyle::BTDS_No);
366     IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
367     IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
368 
369     // For backward compatibility.
370     IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
371     IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
372   }
373 };
374 
375 template <>
376 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
377   static void
378   enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
379     IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
380     IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
381     IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
382 
383     // For backward compatibility.
384     IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
385     IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
386   }
387 };
388 
389 template <>
390 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
391   static void enumeration(IO &IO,
392                           FormatStyle::NamespaceIndentationKind &Value) {
393     IO.enumCase(Value, "None", FormatStyle::NI_None);
394     IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
395     IO.enumCase(Value, "All", FormatStyle::NI_All);
396   }
397 };
398 
399 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
400   static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {
401     IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
402     IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
403     IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
404     IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent);
405 
406     // For backward compatibility.
407     IO.enumCase(Value, "true", FormatStyle::BAS_Align);
408     IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);
409   }
410 };
411 
412 template <>
413 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
414   static void enumeration(IO &IO,
415                           FormatStyle::EscapedNewlineAlignmentStyle &Value) {
416     IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
417     IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
418     IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
419 
420     // For backward compatibility.
421     IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
422     IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
423   }
424 };
425 
426 template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
427   static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
428     IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
429     IO.enumCase(Value, "Align", FormatStyle::OAS_Align);
430     IO.enumCase(Value, "AlignAfterOperator",
431                 FormatStyle::OAS_AlignAfterOperator);
432 
433     // For backward compatibility.
434     IO.enumCase(Value, "true", FormatStyle::OAS_Align);
435     IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);
436   }
437 };
438 
439 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
440   static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
441     IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
442     IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
443     IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
444 
445     // For backward compatibility.
446     IO.enumCase(Value, "true", FormatStyle::PAS_Left);
447     IO.enumCase(Value, "false", FormatStyle::PAS_Right);
448   }
449 };
450 
451 template <>
452 struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> {
453   static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) {
454     IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave);
455     IO.enumCase(Value, "Always", FormatStyle::SDS_Always);
456     IO.enumCase(Value, "Never", FormatStyle::SDS_Never);
457   }
458 };
459 
460 template <>
461 struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
462   static void
463   enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
464     IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
465     IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
466     IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
467     IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
468   }
469 };
470 
471 template <>
472 struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> {
473   static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) {
474     IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer);
475     IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle);
476     IO.enumCase(Value, "Left", FormatStyle::RAS_Left);
477     IO.enumCase(Value, "Right", FormatStyle::RAS_Right);
478   }
479 };
480 
481 template <>
482 struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> {
483   static void enumeration(IO &IO,
484                           FormatStyle::RequiresClausePositionStyle &Value) {
485     IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine);
486     IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding);
487     IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing);
488     IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine);
489   }
490 };
491 
492 template <>
493 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> {
494   static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value) {
495     IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
496     IO.enumCase(Value, "ControlStatements",
497                 FormatStyle::SBPO_ControlStatements);
498     IO.enumCase(Value, "ControlStatementsExceptControlMacros",
499                 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
500     IO.enumCase(Value, "NonEmptyParentheses",
501                 FormatStyle::SBPO_NonEmptyParentheses);
502     IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
503     IO.enumCase(Value, "Custom", FormatStyle::SBPO_Custom);
504 
505     // For backward compatibility.
506     IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
507     IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
508     IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
509                 FormatStyle::SBPO_ControlStatementsExceptControlMacros);
510   }
511 };
512 
513 template <>
514 struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
515   static void enumeration(IO &IO,
516                           FormatStyle::BitFieldColonSpacingStyle &Value) {
517     IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);
518     IO.enumCase(Value, "None", FormatStyle::BFCS_None);
519     IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);
520     IO.enumCase(Value, "After", FormatStyle::BFCS_After);
521   }
522 };
523 
524 template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {
525   static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {
526     IO.enumCase(Value, "Never", FormatStyle::SI_Never);
527     IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);
528     IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);
529 
530     // For backward compatibility.
531     IO.enumCase(Value, "false", FormatStyle::SI_Never);
532     IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);
533   }
534 };
535 
536 template <>
537 struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
538   static void enumeration(IO &IO,
539                           FormatStyle::SortJavaStaticImportOptions &Value) {
540     IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
541     IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
542   }
543 };
544 
545 template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
546   static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
547     IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
548     IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
549     IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
550 
551     // For backward compatibility.
552     IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
553     IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
554   }
555 };
556 
557 template <> struct MappingTraits<FormatStyle> {
558   static void mapping(IO &IO, FormatStyle &Style) {
559     // When reading, read the language first, we need it for getPredefinedStyle.
560     IO.mapOptional("Language", Style.Language);
561 
562     if (IO.outputting()) {
563       StringRef Styles[] = {"LLVM",   "Google", "Chromium", "Mozilla",
564                             "WebKit", "GNU",    "Microsoft"};
565       for (StringRef StyleName : Styles) {
566         FormatStyle PredefinedStyle;
567         if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
568             Style == PredefinedStyle) {
569           IO.mapOptional("# BasedOnStyle", StyleName);
570           break;
571         }
572       }
573     } else {
574       StringRef BasedOnStyle;
575       IO.mapOptional("BasedOnStyle", BasedOnStyle);
576       if (!BasedOnStyle.empty()) {
577         FormatStyle::LanguageKind OldLanguage = Style.Language;
578         FormatStyle::LanguageKind Language =
579             ((FormatStyle *)IO.getContext())->Language;
580         if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
581           IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
582           return;
583         }
584         Style.Language = OldLanguage;
585       }
586     }
587 
588     // For backward compatibility.
589     if (!IO.outputting()) {
590       IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
591       IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
592       IO.mapOptional("IndentFunctionDeclarationAfterType",
593                      Style.IndentWrappedFunctionNames);
594       IO.mapOptional("IndentRequires", Style.IndentRequiresClause);
595       IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
596       IO.mapOptional("SpaceAfterControlStatementKeyword",
597                      Style.SpaceBeforeParens);
598     }
599 
600     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
601     IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
602     IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures);
603     IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
604     IO.mapOptional("AlignConsecutiveAssignments",
605                    Style.AlignConsecutiveAssignments);
606     IO.mapOptional("AlignConsecutiveBitFields",
607                    Style.AlignConsecutiveBitFields);
608     IO.mapOptional("AlignConsecutiveDeclarations",
609                    Style.AlignConsecutiveDeclarations);
610     IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
611     IO.mapOptional("AlignOperands", Style.AlignOperands);
612     IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
613     IO.mapOptional("AllowAllArgumentsOnNextLine",
614                    Style.AllowAllArgumentsOnNextLine);
615     IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
616                    Style.AllowAllParametersOfDeclarationOnNextLine);
617     IO.mapOptional("AllowShortEnumsOnASingleLine",
618                    Style.AllowShortEnumsOnASingleLine);
619     IO.mapOptional("AllowShortBlocksOnASingleLine",
620                    Style.AllowShortBlocksOnASingleLine);
621     IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
622                    Style.AllowShortCaseLabelsOnASingleLine);
623     IO.mapOptional("AllowShortFunctionsOnASingleLine",
624                    Style.AllowShortFunctionsOnASingleLine);
625     IO.mapOptional("AllowShortLambdasOnASingleLine",
626                    Style.AllowShortLambdasOnASingleLine);
627     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
628                    Style.AllowShortIfStatementsOnASingleLine);
629     IO.mapOptional("AllowShortLoopsOnASingleLine",
630                    Style.AllowShortLoopsOnASingleLine);
631     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
632                    Style.AlwaysBreakAfterDefinitionReturnType);
633     IO.mapOptional("AlwaysBreakAfterReturnType",
634                    Style.AlwaysBreakAfterReturnType);
635 
636     // If AlwaysBreakAfterDefinitionReturnType was specified but
637     // AlwaysBreakAfterReturnType was not, initialize the latter from the
638     // former for backwards compatibility.
639     if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
640         Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) {
641       if (Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All)
642         Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
643       else if (Style.AlwaysBreakAfterDefinitionReturnType ==
644                FormatStyle::DRTBS_TopLevel)
645         Style.AlwaysBreakAfterReturnType =
646             FormatStyle::RTBS_TopLevelDefinitions;
647     }
648 
649     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
650                    Style.AlwaysBreakBeforeMultilineStrings);
651     IO.mapOptional("AlwaysBreakTemplateDeclarations",
652                    Style.AlwaysBreakTemplateDeclarations);
653     IO.mapOptional("AttributeMacros", Style.AttributeMacros);
654     IO.mapOptional("BinPackArguments", Style.BinPackArguments);
655     IO.mapOptional("BinPackParameters", Style.BinPackParameters);
656     IO.mapOptional("BraceWrapping", Style.BraceWrapping);
657     IO.mapOptional("BreakBeforeBinaryOperators",
658                    Style.BreakBeforeBinaryOperators);
659     IO.mapOptional("BreakBeforeConceptDeclarations",
660                    Style.BreakBeforeConceptDeclarations);
661     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
662 
663     bool BreakBeforeInheritanceComma = false;
664     IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma);
665     IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
666     // If BreakBeforeInheritanceComma was specified but
667     // BreakInheritance was not, initialize the latter from the
668     // former for backwards compatibility.
669     if (BreakBeforeInheritanceComma &&
670         Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon)
671       Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
672 
673     IO.mapOptional("BreakBeforeTernaryOperators",
674                    Style.BreakBeforeTernaryOperators);
675 
676     bool BreakConstructorInitializersBeforeComma = false;
677     IO.mapOptional("BreakConstructorInitializersBeforeComma",
678                    BreakConstructorInitializersBeforeComma);
679     IO.mapOptional("BreakConstructorInitializers",
680                    Style.BreakConstructorInitializers);
681     // If BreakConstructorInitializersBeforeComma was specified but
682     // BreakConstructorInitializers was not, initialize the latter from the
683     // former for backwards compatibility.
684     if (BreakConstructorInitializersBeforeComma &&
685         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon)
686       Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
687 
688     IO.mapOptional("BreakAfterJavaFieldAnnotations",
689                    Style.BreakAfterJavaFieldAnnotations);
690     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
691     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
692     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
693     IO.mapOptional("QualifierAlignment", Style.QualifierAlignment);
694 
695     // Default Order for Left/Right based Qualifier alignment.
696     if (Style.QualifierAlignment == FormatStyle::QAS_Right)
697       Style.QualifierOrder = {"type", "const", "volatile"};
698     else if (Style.QualifierAlignment == FormatStyle::QAS_Left)
699       Style.QualifierOrder = {"const", "volatile", "type"};
700     else if (Style.QualifierAlignment == FormatStyle::QAS_Custom)
701       IO.mapOptional("QualifierOrder", Style.QualifierOrder);
702 
703     IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
704     IO.mapOptional("ConstructorInitializerIndentWidth",
705                    Style.ConstructorInitializerIndentWidth);
706     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
707     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
708     IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
709     IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
710     IO.mapOptional("DisableFormat", Style.DisableFormat);
711     IO.mapOptional("EmptyLineAfterAccessModifier",
712                    Style.EmptyLineAfterAccessModifier);
713     IO.mapOptional("EmptyLineBeforeAccessModifier",
714                    Style.EmptyLineBeforeAccessModifier);
715     IO.mapOptional("ExperimentalAutoDetectBinPacking",
716                    Style.ExperimentalAutoDetectBinPacking);
717 
718     IO.mapOptional("PackConstructorInitializers",
719                    Style.PackConstructorInitializers);
720     // For backward compatibility:
721     // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was
722     // false unless BasedOnStyle was Google or Chromium whereas that of
723     // AllowAllConstructorInitializersOnNextLine was always true, so the
724     // equivalent default value of PackConstructorInitializers is PCIS_NextLine
725     // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options
726     // had a non-default value while PackConstructorInitializers has a default
727     // value, set the latter to an equivalent non-default value if needed.
728     StringRef BasedOn;
729     IO.mapOptional("BasedOnStyle", BasedOn);
730     const bool IsGoogleOrChromium = BasedOn.equals_insensitive("google") ||
731                                     BasedOn.equals_insensitive("chromium");
732     bool OnCurrentLine = IsGoogleOrChromium;
733     bool OnNextLine = true;
734     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
735                    OnCurrentLine);
736     IO.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine);
737     if (!IsGoogleOrChromium) {
738       if (Style.PackConstructorInitializers == FormatStyle::PCIS_BinPack &&
739           OnCurrentLine) {
740         Style.PackConstructorInitializers = OnNextLine
741                                                 ? FormatStyle::PCIS_NextLine
742                                                 : FormatStyle::PCIS_CurrentLine;
743       }
744     } else if (Style.PackConstructorInitializers ==
745                FormatStyle::PCIS_NextLine) {
746       if (!OnCurrentLine)
747         Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
748       else if (!OnNextLine)
749         Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine;
750     }
751 
752     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
753     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
754     IO.mapOptional("IfMacros", Style.IfMacros);
755 
756     IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
757     IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
758     IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
759     IO.mapOptional("IncludeIsMainSourceRegex",
760                    Style.IncludeStyle.IncludeIsMainSourceRegex);
761     IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
762     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
763     IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
764     IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
765     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
766     IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
767     IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause);
768     IO.mapOptional("IndentWidth", Style.IndentWidth);
769     IO.mapOptional("IndentWrappedFunctionNames",
770                    Style.IndentWrappedFunctionNames);
771     IO.mapOptional("InsertBraces", Style.InsertBraces);
772     IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
773     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
774     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
775     IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
776     IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
777                    Style.KeepEmptyLinesAtTheStartOfBlocks);
778     IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
779     IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
780     IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
781     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
782     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
783     IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
784     IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
785     IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
786     IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
787                    Style.ObjCBreakBeforeNestedBlockParam);
788     IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
789     IO.mapOptional("ObjCSpaceBeforeProtocolList",
790                    Style.ObjCSpaceBeforeProtocolList);
791     IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
792     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
793                    Style.PenaltyBreakBeforeFirstCallParameter);
794     IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
795     IO.mapOptional("PenaltyBreakFirstLessLess",
796                    Style.PenaltyBreakFirstLessLess);
797     IO.mapOptional("PenaltyBreakOpenParenthesis",
798                    Style.PenaltyBreakOpenParenthesis);
799     IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
800     IO.mapOptional("PenaltyBreakTemplateDeclaration",
801                    Style.PenaltyBreakTemplateDeclaration);
802     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
803     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
804                    Style.PenaltyReturnTypeOnItsOwnLine);
805     IO.mapOptional("PenaltyIndentedWhitespace",
806                    Style.PenaltyIndentedWhitespace);
807     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
808     IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);
809     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
810     IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
811     IO.mapOptional("ReflowComments", Style.ReflowComments);
812     IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
813     IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
814     IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
815     IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
816     IO.mapOptional("SortIncludes", Style.SortIncludes);
817     IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
818     IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
819     IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
820     IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
821     IO.mapOptional("SpaceAfterTemplateKeyword",
822                    Style.SpaceAfterTemplateKeyword);
823     IO.mapOptional("SpaceBeforeAssignmentOperators",
824                    Style.SpaceBeforeAssignmentOperators);
825     IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
826     IO.mapOptional("SpaceBeforeCpp11BracedList",
827                    Style.SpaceBeforeCpp11BracedList);
828     IO.mapOptional("SpaceBeforeCtorInitializerColon",
829                    Style.SpaceBeforeCtorInitializerColon);
830     IO.mapOptional("SpaceBeforeInheritanceColon",
831                    Style.SpaceBeforeInheritanceColon);
832     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
833     IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions);
834     IO.mapOptional("SpaceAroundPointerQualifiers",
835                    Style.SpaceAroundPointerQualifiers);
836     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
837                    Style.SpaceBeforeRangeBasedForLoopColon);
838     IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
839     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
840     IO.mapOptional("SpacesBeforeTrailingComments",
841                    Style.SpacesBeforeTrailingComments);
842     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
843     IO.mapOptional("SpacesInConditionalStatement",
844                    Style.SpacesInConditionalStatement);
845     IO.mapOptional("SpacesInContainerLiterals",
846                    Style.SpacesInContainerLiterals);
847     IO.mapOptional("SpacesInCStyleCastParentheses",
848                    Style.SpacesInCStyleCastParentheses);
849     IO.mapOptional("SpacesInLineCommentPrefix",
850                    Style.SpacesInLineCommentPrefix);
851     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
852     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
853     IO.mapOptional("SpaceBeforeSquareBrackets",
854                    Style.SpaceBeforeSquareBrackets);
855     IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing);
856     IO.mapOptional("Standard", Style.Standard);
857     IO.mapOptional("StatementAttributeLikeMacros",
858                    Style.StatementAttributeLikeMacros);
859     IO.mapOptional("StatementMacros", Style.StatementMacros);
860     IO.mapOptional("TabWidth", Style.TabWidth);
861     IO.mapOptional("TypenameMacros", Style.TypenameMacros);
862     IO.mapOptional("UseCRLF", Style.UseCRLF);
863     IO.mapOptional("UseTab", Style.UseTab);
864     IO.mapOptional("WhitespaceSensitiveMacros",
865                    Style.WhitespaceSensitiveMacros);
866   }
867 };
868 
869 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
870   static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
871     IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
872     IO.mapOptional("AfterClass", Wrapping.AfterClass);
873     IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
874     IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
875     IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
876     IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
877     IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
878     IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
879     IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
880     IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
881     IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
882     IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
883     IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
884     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
885     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
886     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
887     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
888     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
889   }
890 };
891 
892 template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> {
893   static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {
894     IO.mapOptional("AfterControlStatements", Spacing.AfterControlStatements);
895     IO.mapOptional("AfterForeachMacros", Spacing.AfterForeachMacros);
896     IO.mapOptional("AfterFunctionDefinitionName",
897                    Spacing.AfterFunctionDefinitionName);
898     IO.mapOptional("AfterFunctionDeclarationName",
899                    Spacing.AfterFunctionDeclarationName);
900     IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
901     IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
902     IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause);
903     IO.mapOptional("AfterRequiresInExpression",
904                    Spacing.AfterRequiresInExpression);
905     IO.mapOptional("BeforeNonEmptyParentheses",
906                    Spacing.BeforeNonEmptyParentheses);
907   }
908 };
909 
910 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
911   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
912     IO.mapOptional("Language", Format.Language);
913     IO.mapOptional("Delimiters", Format.Delimiters);
914     IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
915     IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
916     IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
917   }
918 };
919 
920 template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
921   static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
922     // Transform the maximum to signed, to parse "-1" correctly
923     int signedMaximum = static_cast<int>(Space.Maximum);
924     IO.mapOptional("Minimum", Space.Minimum);
925     IO.mapOptional("Maximum", signedMaximum);
926     Space.Maximum = static_cast<unsigned>(signedMaximum);
927 
928     if (Space.Maximum != -1u)
929       Space.Minimum = std::min(Space.Minimum, Space.Maximum);
930   }
931 };
932 
933 // Allows to read vector<FormatStyle> while keeping default values.
934 // IO.getContext() should contain a pointer to the FormatStyle structure, that
935 // will be used to get default values for missing keys.
936 // If the first element has no Language specified, it will be treated as the
937 // default one for the following elements.
938 template <> struct DocumentListTraits<std::vector<FormatStyle>> {
939   static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
940     return Seq.size();
941   }
942   static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
943                               size_t Index) {
944     if (Index >= Seq.size()) {
945       assert(Index == Seq.size());
946       FormatStyle Template;
947       if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
948         Template = Seq[0];
949       } else {
950         Template = *((const FormatStyle *)IO.getContext());
951         Template.Language = FormatStyle::LK_None;
952       }
953       Seq.resize(Index + 1, Template);
954     }
955     return Seq[Index];
956   }
957 };
958 } // namespace yaml
959 } // namespace llvm
960 
961 namespace clang {
962 namespace format {
963 
964 const std::error_category &getParseCategory() {
965   static const ParseErrorCategory C{};
966   return C;
967 }
968 std::error_code make_error_code(ParseError e) {
969   return std::error_code(static_cast<int>(e), getParseCategory());
970 }
971 
972 inline llvm::Error make_string_error(const llvm::Twine &Message) {
973   return llvm::make_error<llvm::StringError>(Message,
974                                              llvm::inconvertibleErrorCode());
975 }
976 
977 const char *ParseErrorCategory::name() const noexcept {
978   return "clang-format.parse_error";
979 }
980 
981 std::string ParseErrorCategory::message(int EV) const {
982   switch (static_cast<ParseError>(EV)) {
983   case ParseError::Success:
984     return "Success";
985   case ParseError::Error:
986     return "Invalid argument";
987   case ParseError::Unsuitable:
988     return "Unsuitable";
989   case ParseError::BinPackTrailingCommaConflict:
990     return "trailing comma insertion cannot be used with bin packing";
991   case ParseError::InvalidQualifierSpecified:
992     return "Invalid qualifier specified in QualifierOrder";
993   case ParseError::DuplicateQualifierSpecified:
994     return "Duplicate qualifier specified in QualifierOrder";
995   case ParseError::MissingQualifierType:
996     return "Missing type in QualifierOrder";
997   case ParseError::MissingQualifierOrder:
998     return "Missing QualifierOrder";
999   }
1000   llvm_unreachable("unexpected parse error");
1001 }
1002 
1003 static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
1004   if (Expanded.BreakBeforeBraces == FormatStyle::BS_Custom)
1005     return;
1006   Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
1007                             /*AfterClass=*/false,
1008                             /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1009                             /*AfterEnum=*/false,
1010                             /*AfterFunction=*/false,
1011                             /*AfterNamespace=*/false,
1012                             /*AfterObjCDeclaration=*/false,
1013                             /*AfterStruct=*/false,
1014                             /*AfterUnion=*/false,
1015                             /*AfterExternBlock=*/false,
1016                             /*BeforeCatch=*/false,
1017                             /*BeforeElse=*/false,
1018                             /*BeforeLambdaBody=*/false,
1019                             /*BeforeWhile=*/false,
1020                             /*IndentBraces=*/false,
1021                             /*SplitEmptyFunction=*/true,
1022                             /*SplitEmptyRecord=*/true,
1023                             /*SplitEmptyNamespace=*/true};
1024   switch (Expanded.BreakBeforeBraces) {
1025   case FormatStyle::BS_Linux:
1026     Expanded.BraceWrapping.AfterClass = true;
1027     Expanded.BraceWrapping.AfterFunction = true;
1028     Expanded.BraceWrapping.AfterNamespace = true;
1029     break;
1030   case FormatStyle::BS_Mozilla:
1031     Expanded.BraceWrapping.AfterClass = true;
1032     Expanded.BraceWrapping.AfterEnum = true;
1033     Expanded.BraceWrapping.AfterFunction = true;
1034     Expanded.BraceWrapping.AfterStruct = true;
1035     Expanded.BraceWrapping.AfterUnion = true;
1036     Expanded.BraceWrapping.AfterExternBlock = true;
1037     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1038     Expanded.BraceWrapping.SplitEmptyFunction = true;
1039     Expanded.BraceWrapping.SplitEmptyRecord = false;
1040     break;
1041   case FormatStyle::BS_Stroustrup:
1042     Expanded.BraceWrapping.AfterFunction = true;
1043     Expanded.BraceWrapping.BeforeCatch = true;
1044     Expanded.BraceWrapping.BeforeElse = true;
1045     break;
1046   case FormatStyle::BS_Allman:
1047     Expanded.BraceWrapping.AfterCaseLabel = true;
1048     Expanded.BraceWrapping.AfterClass = true;
1049     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1050     Expanded.BraceWrapping.AfterEnum = true;
1051     Expanded.BraceWrapping.AfterFunction = true;
1052     Expanded.BraceWrapping.AfterNamespace = true;
1053     Expanded.BraceWrapping.AfterObjCDeclaration = true;
1054     Expanded.BraceWrapping.AfterStruct = true;
1055     Expanded.BraceWrapping.AfterUnion = true;
1056     Expanded.BraceWrapping.AfterExternBlock = true;
1057     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1058     Expanded.BraceWrapping.BeforeCatch = true;
1059     Expanded.BraceWrapping.BeforeElse = true;
1060     Expanded.BraceWrapping.BeforeLambdaBody = true;
1061     break;
1062   case FormatStyle::BS_Whitesmiths:
1063     Expanded.BraceWrapping.AfterCaseLabel = true;
1064     Expanded.BraceWrapping.AfterClass = true;
1065     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1066     Expanded.BraceWrapping.AfterEnum = true;
1067     Expanded.BraceWrapping.AfterFunction = true;
1068     Expanded.BraceWrapping.AfterNamespace = true;
1069     Expanded.BraceWrapping.AfterObjCDeclaration = true;
1070     Expanded.BraceWrapping.AfterStruct = true;
1071     Expanded.BraceWrapping.AfterExternBlock = true;
1072     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1073     Expanded.BraceWrapping.BeforeCatch = true;
1074     Expanded.BraceWrapping.BeforeElse = true;
1075     Expanded.BraceWrapping.BeforeLambdaBody = true;
1076     break;
1077   case FormatStyle::BS_GNU:
1078     Expanded.BraceWrapping = {
1079         /*AfterCaseLabel=*/true,
1080         /*AfterClass=*/true,
1081         /*AfterControlStatement=*/FormatStyle::BWACS_Always,
1082         /*AfterEnum=*/true,
1083         /*AfterFunction=*/true,
1084         /*AfterNamespace=*/true,
1085         /*AfterObjCDeclaration=*/true,
1086         /*AfterStruct=*/true,
1087         /*AfterUnion=*/true,
1088         /*AfterExternBlock=*/true,
1089         /*BeforeCatch=*/true,
1090         /*BeforeElse=*/true,
1091         /*BeforeLambdaBody=*/false,
1092         /*BeforeWhile=*/true,
1093         /*IndentBraces=*/true,
1094         /*SplitEmptyFunction=*/true,
1095         /*SplitEmptyRecord=*/true,
1096         /*SplitEmptyNamespace=*/true};
1097     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1098     break;
1099   case FormatStyle::BS_WebKit:
1100     Expanded.BraceWrapping.AfterFunction = true;
1101     break;
1102   default:
1103     break;
1104   }
1105 }
1106 
1107 static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded) {
1108   if (Expanded.SpaceBeforeParens == FormatStyle::SBPO_Custom)
1109     return;
1110   // Reset all flags
1111   Expanded.SpaceBeforeParensOptions = {};
1112 
1113   switch (Expanded.SpaceBeforeParens) {
1114   case FormatStyle::SBPO_Never:
1115     break;
1116   case FormatStyle::SBPO_ControlStatements:
1117     Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1118     Expanded.SpaceBeforeParensOptions.AfterForeachMacros = true;
1119     Expanded.SpaceBeforeParensOptions.AfterIfMacros = true;
1120     break;
1121   case FormatStyle::SBPO_ControlStatementsExceptControlMacros:
1122     Expanded.SpaceBeforeParensOptions.AfterControlStatements = true;
1123     break;
1124   case FormatStyle::SBPO_NonEmptyParentheses:
1125     Expanded.SpaceBeforeParensOptions.BeforeNonEmptyParentheses = true;
1126     break;
1127   case FormatStyle::SBPO_Always:
1128     break;
1129   default:
1130     break;
1131   }
1132 }
1133 
1134 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
1135   FormatStyle LLVMStyle;
1136   LLVMStyle.InheritsParentConfig = false;
1137   LLVMStyle.Language = Language;
1138   LLVMStyle.AccessModifierOffset = -2;
1139   LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
1140   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
1141   LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
1142   LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
1143   LLVMStyle.AlignTrailingComments = true;
1144   LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
1145   LLVMStyle.AlignConsecutiveBitFields = FormatStyle::ACS_None;
1146   LLVMStyle.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
1147   LLVMStyle.AlignConsecutiveMacros = FormatStyle::ACS_None;
1148   LLVMStyle.AllowAllArgumentsOnNextLine = true;
1149   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
1150   LLVMStyle.AllowShortEnumsOnASingleLine = true;
1151   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
1152   LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
1153   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
1154   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1155   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
1156   LLVMStyle.AllowShortLoopsOnASingleLine = false;
1157   LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
1158   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1159   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
1160   LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
1161   LLVMStyle.AttributeMacros.push_back("__capability");
1162   LLVMStyle.BinPackArguments = true;
1163   LLVMStyle.BinPackParameters = true;
1164   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
1165   LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
1166   LLVMStyle.BreakBeforeTernaryOperators = true;
1167   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
1168   LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
1169                              /*AfterClass=*/false,
1170                              /*AfterControlStatement=*/FormatStyle::BWACS_Never,
1171                              /*AfterEnum=*/false,
1172                              /*AfterFunction=*/false,
1173                              /*AfterNamespace=*/false,
1174                              /*AfterObjCDeclaration=*/false,
1175                              /*AfterStruct=*/false,
1176                              /*AfterUnion=*/false,
1177                              /*AfterExternBlock=*/false,
1178                              /*BeforeCatch=*/false,
1179                              /*BeforeElse=*/false,
1180                              /*BeforeLambdaBody=*/false,
1181                              /*BeforeWhile=*/false,
1182                              /*IndentBraces=*/false,
1183                              /*SplitEmptyFunction=*/true,
1184                              /*SplitEmptyRecord=*/true,
1185                              /*SplitEmptyNamespace=*/true};
1186   LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1187   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
1188   LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
1189   LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
1190   LLVMStyle.BreakStringLiterals = true;
1191   LLVMStyle.ColumnLimit = 80;
1192   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
1193   LLVMStyle.CompactNamespaces = false;
1194   LLVMStyle.ConstructorInitializerIndentWidth = 4;
1195   LLVMStyle.ContinuationIndentWidth = 4;
1196   LLVMStyle.Cpp11BracedListStyle = true;
1197 
1198   // Off by default Qualifier ordering
1199   LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave;
1200 
1201   LLVMStyle.DeriveLineEnding = true;
1202   LLVMStyle.DerivePointerAlignment = false;
1203   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
1204   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
1205   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1206   LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
1207   LLVMStyle.FixNamespaceComments = true;
1208   LLVMStyle.ForEachMacros.push_back("foreach");
1209   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1210   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1211   LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
1212   LLVMStyle.IncludeStyle.IncludeCategories = {
1213       {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1214       {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1215       {".*", 1, 0, false}};
1216   LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1217   LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
1218   LLVMStyle.IndentAccessModifiers = false;
1219   LLVMStyle.IndentCaseLabels = false;
1220   LLVMStyle.IndentCaseBlocks = false;
1221   LLVMStyle.IndentGotoLabels = true;
1222   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
1223   LLVMStyle.IndentRequiresClause = true;
1224   LLVMStyle.IndentWrappedFunctionNames = false;
1225   LLVMStyle.IndentWidth = 2;
1226   LLVMStyle.PPIndentWidth = -1;
1227   LLVMStyle.InsertBraces = false;
1228   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1229   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
1230   LLVMStyle.JavaScriptWrapImports = true;
1231   LLVMStyle.TabWidth = 8;
1232   LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature;
1233   LLVMStyle.MaxEmptyLinesToKeep = 1;
1234   LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
1235   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
1236   LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
1237   LLVMStyle.ObjCBlockIndentWidth = 2;
1238   LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1239   LLVMStyle.ObjCSpaceAfterProperty = false;
1240   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1241   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
1242   LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
1243   LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine;
1244   LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
1245   LLVMStyle.ShortNamespaceLines = 1;
1246   LLVMStyle.SpacesBeforeTrailingComments = 1;
1247   LLVMStyle.Standard = FormatStyle::LS_Latest;
1248   LLVMStyle.UseCRLF = false;
1249   LLVMStyle.UseTab = FormatStyle::UT_Never;
1250   LLVMStyle.ReflowComments = true;
1251   LLVMStyle.RemoveBracesLLVM = false;
1252   LLVMStyle.SpacesInParentheses = false;
1253   LLVMStyle.SpacesInSquareBrackets = false;
1254   LLVMStyle.SpaceInEmptyBlock = false;
1255   LLVMStyle.SpaceInEmptyParentheses = false;
1256   LLVMStyle.SpacesInContainerLiterals = true;
1257   LLVMStyle.SpacesInCStyleCastParentheses = false;
1258   LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
1259   LLVMStyle.SpaceAfterCStyleCast = false;
1260   LLVMStyle.SpaceAfterLogicalNot = false;
1261   LLVMStyle.SpaceAfterTemplateKeyword = true;
1262   LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
1263   LLVMStyle.SpaceBeforeCaseColon = false;
1264   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1265   LLVMStyle.SpaceBeforeInheritanceColon = true;
1266   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
1267   LLVMStyle.SpaceBeforeParensOptions = {};
1268   LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true;
1269   LLVMStyle.SpaceBeforeParensOptions.AfterForeachMacros = true;
1270   LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true;
1271   LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1272   LLVMStyle.SpaceBeforeAssignmentOperators = true;
1273   LLVMStyle.SpaceBeforeCpp11BracedList = false;
1274   LLVMStyle.SpaceBeforeSquareBrackets = false;
1275   LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
1276   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
1277   LLVMStyle.SpacesInConditionalStatement = false;
1278 
1279   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
1280   LLVMStyle.PenaltyBreakComment = 300;
1281   LLVMStyle.PenaltyBreakFirstLessLess = 120;
1282   LLVMStyle.PenaltyBreakString = 1000;
1283   LLVMStyle.PenaltyExcessCharacter = 1000000;
1284   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1285   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
1286   LLVMStyle.PenaltyBreakOpenParenthesis = 0;
1287   LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
1288   LLVMStyle.PenaltyIndentedWhitespace = 0;
1289 
1290   LLVMStyle.DisableFormat = false;
1291   LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1292   LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
1293   LLVMStyle.SortUsingDeclarations = true;
1294   LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1295   LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1296   LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1297   LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1298   LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1299   LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1300   LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1301   LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1302 
1303   // Defaults that differ when not C++.
1304   if (Language == FormatStyle::LK_TableGen)
1305     LLVMStyle.SpacesInContainerLiterals = false;
1306   if (LLVMStyle.isJson())
1307     LLVMStyle.ColumnLimit = 0;
1308 
1309   return LLVMStyle;
1310 }
1311 
1312 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
1313   if (Language == FormatStyle::LK_TextProto) {
1314     FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
1315     GoogleStyle.Language = FormatStyle::LK_TextProto;
1316 
1317     return GoogleStyle;
1318   }
1319 
1320   FormatStyle GoogleStyle = getLLVMStyle(Language);
1321 
1322   GoogleStyle.AccessModifierOffset = -1;
1323   GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
1324   GoogleStyle.AllowShortIfStatementsOnASingleLine =
1325       FormatStyle::SIS_WithoutElse;
1326   GoogleStyle.AllowShortLoopsOnASingleLine = true;
1327   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1328   GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1329   GoogleStyle.DerivePointerAlignment = true;
1330   GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1331                                                 {"^<.*\\.h>", 1, 0, false},
1332                                                 {"^<.*", 2, 0, false},
1333                                                 {".*", 3, 0, false}};
1334   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1335   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1336   GoogleStyle.IndentCaseLabels = true;
1337   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
1338   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
1339   GoogleStyle.ObjCSpaceAfterProperty = false;
1340   GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1341   GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
1342   GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
1343   GoogleStyle.RawStringFormats = {
1344       {
1345           FormatStyle::LK_Cpp,
1346           /*Delimiters=*/
1347           {
1348               "cc",
1349               "CC",
1350               "cpp",
1351               "Cpp",
1352               "CPP",
1353               "c++",
1354               "C++",
1355           },
1356           /*EnclosingFunctionNames=*/
1357           {},
1358           /*CanonicalDelimiter=*/"",
1359           /*BasedOnStyle=*/"google",
1360       },
1361       {
1362           FormatStyle::LK_TextProto,
1363           /*Delimiters=*/
1364           {
1365               "pb",
1366               "PB",
1367               "proto",
1368               "PROTO",
1369           },
1370           /*EnclosingFunctionNames=*/
1371           {
1372               "EqualsProto",
1373               "EquivToProto",
1374               "PARSE_PARTIAL_TEXT_PROTO",
1375               "PARSE_TEST_PROTO",
1376               "PARSE_TEXT_PROTO",
1377               "ParseTextOrDie",
1378               "ParseTextProtoOrDie",
1379               "ParseTestProto",
1380               "ParsePartialTestProto",
1381           },
1382           /*CanonicalDelimiter=*/"pb",
1383           /*BasedOnStyle=*/"google",
1384       },
1385   };
1386   GoogleStyle.SpacesBeforeTrailingComments = 2;
1387   GoogleStyle.Standard = FormatStyle::LS_Auto;
1388 
1389   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1390   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
1391 
1392   if (Language == FormatStyle::LK_Java) {
1393     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1394     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1395     GoogleStyle.AlignTrailingComments = false;
1396     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1397     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1398     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1399     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
1400     GoogleStyle.ColumnLimit = 100;
1401     GoogleStyle.SpaceAfterCStyleCast = true;
1402     GoogleStyle.SpacesBeforeTrailingComments = 1;
1403   } else if (Language == FormatStyle::LK_JavaScript) {
1404     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
1405     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1406     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1407     // TODO: still under discussion whether to switch to SLS_All.
1408     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
1409     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1410     GoogleStyle.BreakBeforeTernaryOperators = false;
1411     // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1412     // commonly followed by overlong URLs.
1413     GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1414     // TODO: enable once decided, in particular re disabling bin packing.
1415     // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1416     // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1417     GoogleStyle.MaxEmptyLinesToKeep = 3;
1418     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1419     GoogleStyle.SpacesInContainerLiterals = false;
1420     GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
1421     GoogleStyle.JavaScriptWrapImports = false;
1422   } else if (Language == FormatStyle::LK_Proto) {
1423     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1424     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1425     GoogleStyle.SpacesInContainerLiterals = false;
1426     GoogleStyle.Cpp11BracedListStyle = false;
1427     // This affects protocol buffer options specifications and text protos.
1428     // Text protos are currently mostly formatted inside C++ raw string literals
1429     // and often the current breaking behavior of string literals is not
1430     // beneficial there. Investigate turning this on once proper string reflow
1431     // has been implemented.
1432     GoogleStyle.BreakStringLiterals = false;
1433   } else if (Language == FormatStyle::LK_ObjC) {
1434     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1435     GoogleStyle.ColumnLimit = 100;
1436     // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1437     // relationship between ObjC standard library headers and other heades,
1438     // #imports, etc.)
1439     GoogleStyle.IncludeStyle.IncludeBlocks =
1440         tooling::IncludeStyle::IBS_Preserve;
1441   } else if (Language == FormatStyle::LK_CSharp) {
1442     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1443     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1444     GoogleStyle.BreakStringLiterals = false;
1445     GoogleStyle.ColumnLimit = 100;
1446     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1447   }
1448 
1449   return GoogleStyle;
1450 }
1451 
1452 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
1453   FormatStyle ChromiumStyle = getGoogleStyle(Language);
1454 
1455   // Disable include reordering across blocks in Chromium code.
1456   // - clang-format tries to detect that foo.h is the "main" header for
1457   //   foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1458   //   uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1459   //   _private.cc, _impl.cc etc) in different permutations
1460   //   (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1461   //   better default for Chromium code.
1462   // - The default for .cc and .mm files is different (r357695) for Google style
1463   //   for the same reason. The plan is to unify this again once the main
1464   //   header detection works for Google's ObjC code, but this hasn't happened
1465   //   yet. Since Chromium has some ObjC code, switching Chromium is blocked
1466   //   on that.
1467   // - Finally, "If include reordering is harmful, put things in different
1468   //   blocks to prevent it" has been a recommendation for a long time that
1469   //   people are used to. We'll need a dev education push to change this to
1470   //   "If include reordering is harmful, put things in a different block and
1471   //   _prepend that with a comment_ to prevent it" before changing behavior.
1472   ChromiumStyle.IncludeStyle.IncludeBlocks =
1473       tooling::IncludeStyle::IBS_Preserve;
1474 
1475   if (Language == FormatStyle::LK_Java) {
1476     ChromiumStyle.AllowShortIfStatementsOnASingleLine =
1477         FormatStyle::SIS_WithoutElse;
1478     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
1479     ChromiumStyle.ContinuationIndentWidth = 8;
1480     ChromiumStyle.IndentWidth = 4;
1481     // See styleguide for import groups:
1482     // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
1483     ChromiumStyle.JavaImportGroups = {
1484         "android",
1485         "androidx",
1486         "com",
1487         "dalvik",
1488         "junit",
1489         "org",
1490         "com.google.android.apps.chrome",
1491         "org.chromium",
1492         "java",
1493         "javax",
1494     };
1495     ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1496   } else if (Language == FormatStyle::LK_JavaScript) {
1497     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1498     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1499   } else {
1500     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1501     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1502     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1503     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1504     ChromiumStyle.BinPackParameters = false;
1505     ChromiumStyle.DerivePointerAlignment = false;
1506     if (Language == FormatStyle::LK_ObjC)
1507       ChromiumStyle.ColumnLimit = 80;
1508   }
1509   return ChromiumStyle;
1510 }
1511 
1512 FormatStyle getMozillaStyle() {
1513   FormatStyle MozillaStyle = getLLVMStyle();
1514   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1515   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1516   MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel;
1517   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
1518       FormatStyle::DRTBS_TopLevel;
1519   MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1520   MozillaStyle.BinPackParameters = false;
1521   MozillaStyle.BinPackArguments = false;
1522   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
1523   MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1524   MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1525   MozillaStyle.ConstructorInitializerIndentWidth = 2;
1526   MozillaStyle.ContinuationIndentWidth = 2;
1527   MozillaStyle.Cpp11BracedListStyle = false;
1528   MozillaStyle.FixNamespaceComments = false;
1529   MozillaStyle.IndentCaseLabels = true;
1530   MozillaStyle.ObjCSpaceAfterProperty = true;
1531   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
1532   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1533   MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
1534   MozillaStyle.SpaceAfterTemplateKeyword = false;
1535   return MozillaStyle;
1536 }
1537 
1538 FormatStyle getWebKitStyle() {
1539   FormatStyle Style = getLLVMStyle();
1540   Style.AccessModifierOffset = -4;
1541   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1542   Style.AlignOperands = FormatStyle::OAS_DontAlign;
1543   Style.AlignTrailingComments = false;
1544   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1545   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1546   Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
1547   Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1548   Style.Cpp11BracedListStyle = false;
1549   Style.ColumnLimit = 0;
1550   Style.FixNamespaceComments = false;
1551   Style.IndentWidth = 4;
1552   Style.NamespaceIndentation = FormatStyle::NI_Inner;
1553   Style.ObjCBlockIndentWidth = 4;
1554   Style.ObjCSpaceAfterProperty = true;
1555   Style.PointerAlignment = FormatStyle::PAS_Left;
1556   Style.SpaceBeforeCpp11BracedList = true;
1557   Style.SpaceInEmptyBlock = true;
1558   return Style;
1559 }
1560 
1561 FormatStyle getGNUStyle() {
1562   FormatStyle Style = getLLVMStyle();
1563   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
1564   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1565   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1566   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
1567   Style.BreakBeforeTernaryOperators = true;
1568   Style.Cpp11BracedListStyle = false;
1569   Style.ColumnLimit = 79;
1570   Style.FixNamespaceComments = false;
1571   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
1572   Style.Standard = FormatStyle::LS_Cpp03;
1573   return Style;
1574 }
1575 
1576 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
1577   FormatStyle Style = getLLVMStyle(Language);
1578   Style.ColumnLimit = 120;
1579   Style.TabWidth = 4;
1580   Style.IndentWidth = 4;
1581   Style.UseTab = FormatStyle::UT_Never;
1582   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1583   Style.BraceWrapping.AfterClass = true;
1584   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1585   Style.BraceWrapping.AfterEnum = true;
1586   Style.BraceWrapping.AfterFunction = true;
1587   Style.BraceWrapping.AfterNamespace = true;
1588   Style.BraceWrapping.AfterObjCDeclaration = true;
1589   Style.BraceWrapping.AfterStruct = true;
1590   Style.BraceWrapping.AfterExternBlock = true;
1591   Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1592   Style.BraceWrapping.BeforeCatch = true;
1593   Style.BraceWrapping.BeforeElse = true;
1594   Style.BraceWrapping.BeforeWhile = false;
1595   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
1596   Style.AllowShortEnumsOnASingleLine = false;
1597   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
1598   Style.AllowShortCaseLabelsOnASingleLine = false;
1599   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1600   Style.AllowShortLoopsOnASingleLine = false;
1601   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1602   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
1603   return Style;
1604 }
1605 
1606 FormatStyle getNoStyle() {
1607   FormatStyle NoStyle = getLLVMStyle();
1608   NoStyle.DisableFormat = true;
1609   NoStyle.SortIncludes = FormatStyle::SI_Never;
1610   NoStyle.SortUsingDeclarations = false;
1611   return NoStyle;
1612 }
1613 
1614 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
1615                         FormatStyle *Style) {
1616   if (Name.equals_insensitive("llvm"))
1617     *Style = getLLVMStyle(Language);
1618   else if (Name.equals_insensitive("chromium"))
1619     *Style = getChromiumStyle(Language);
1620   else if (Name.equals_insensitive("mozilla"))
1621     *Style = getMozillaStyle();
1622   else if (Name.equals_insensitive("google"))
1623     *Style = getGoogleStyle(Language);
1624   else if (Name.equals_insensitive("webkit"))
1625     *Style = getWebKitStyle();
1626   else if (Name.equals_insensitive("gnu"))
1627     *Style = getGNUStyle();
1628   else if (Name.equals_insensitive("microsoft"))
1629     *Style = getMicrosoftStyle(Language);
1630   else if (Name.equals_insensitive("none"))
1631     *Style = getNoStyle();
1632   else if (Name.equals_insensitive("inheritparentconfig"))
1633     Style->InheritsParentConfig = true;
1634   else
1635     return false;
1636 
1637   Style->Language = Language;
1638   return true;
1639 }
1640 
1641 ParseError validateQualifierOrder(FormatStyle *Style) {
1642   // If its empty then it means don't do anything.
1643   if (Style->QualifierOrder.empty())
1644     return ParseError::MissingQualifierOrder;
1645 
1646   // Ensure the list contains only currently valid qualifiers.
1647   for (const auto &Qualifier : Style->QualifierOrder) {
1648     if (Qualifier == "type")
1649       continue;
1650     auto token =
1651         LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier);
1652     if (token == tok::identifier)
1653       return ParseError::InvalidQualifierSpecified;
1654   }
1655 
1656   // Ensure the list is unique (no duplicates).
1657   std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(),
1658                                          Style->QualifierOrder.end());
1659   if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {
1660     LLVM_DEBUG(llvm::dbgs()
1661                << "Duplicate Qualifiers " << Style->QualifierOrder.size()
1662                << " vs " << UniqueQualifiers.size() << "\n");
1663     return ParseError::DuplicateQualifierSpecified;
1664   }
1665 
1666   // Ensure the list has 'type' in it.
1667   auto type = std::find(Style->QualifierOrder.begin(),
1668                         Style->QualifierOrder.end(), "type");
1669   if (type == Style->QualifierOrder.end())
1670     return ParseError::MissingQualifierType;
1671 
1672   return ParseError::Success;
1673 }
1674 
1675 std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
1676                                    FormatStyle *Style, bool AllowUnknownOptions,
1677                                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
1678                                    void *DiagHandlerCtxt) {
1679   assert(Style);
1680   FormatStyle::LanguageKind Language = Style->Language;
1681   assert(Language != FormatStyle::LK_None);
1682   if (Config.getBuffer().trim().empty())
1683     return make_error_code(ParseError::Error);
1684   Style->StyleSet.Clear();
1685   std::vector<FormatStyle> Styles;
1686   llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
1687                           DiagHandlerCtxt);
1688   // DocumentListTraits<vector<FormatStyle>> uses the context to get default
1689   // values for the fields, keys for which are missing from the configuration.
1690   // Mapping also uses the context to get the language to find the correct
1691   // base style.
1692   Input.setContext(Style);
1693   Input.setAllowUnknownKeys(AllowUnknownOptions);
1694   Input >> Styles;
1695   if (Input.error())
1696     return Input.error();
1697 
1698   for (unsigned i = 0; i < Styles.size(); ++i) {
1699     // Ensures that only the first configuration can skip the Language option.
1700     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
1701       return make_error_code(ParseError::Error);
1702     // Ensure that each language is configured at most once.
1703     for (unsigned j = 0; j < i; ++j) {
1704       if (Styles[i].Language == Styles[j].Language) {
1705         LLVM_DEBUG(llvm::dbgs()
1706                    << "Duplicate languages in the config file on positions "
1707                    << j << " and " << i << "\n");
1708         return make_error_code(ParseError::Error);
1709       }
1710     }
1711   }
1712   // Look for a suitable configuration starting from the end, so we can
1713   // find the configuration for the specific language first, and the default
1714   // configuration (which can only be at slot 0) after it.
1715   FormatStyle::FormatStyleSet StyleSet;
1716   bool LanguageFound = false;
1717   for (const FormatStyle &Style : llvm::reverse(Styles)) {
1718     if (Style.Language != FormatStyle::LK_None)
1719       StyleSet.Add(Style);
1720     if (Style.Language == Language)
1721       LanguageFound = true;
1722   }
1723   if (!LanguageFound) {
1724     if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
1725       return make_error_code(ParseError::Unsuitable);
1726     FormatStyle DefaultStyle = Styles[0];
1727     DefaultStyle.Language = Language;
1728     StyleSet.Add(std::move(DefaultStyle));
1729   }
1730   *Style = *StyleSet.Get(Language);
1731   if (Style->InsertTrailingCommas != FormatStyle::TCS_None &&
1732       Style->BinPackArguments) {
1733     // See comment on FormatStyle::TSC_Wrapped.
1734     return make_error_code(ParseError::BinPackTrailingCommaConflict);
1735   }
1736   if (Style->QualifierAlignment != FormatStyle::QAS_Leave)
1737     return make_error_code(validateQualifierOrder(Style));
1738   return make_error_code(ParseError::Success);
1739 }
1740 
1741 std::string configurationAsText(const FormatStyle &Style) {
1742   std::string Text;
1743   llvm::raw_string_ostream Stream(Text);
1744   llvm::yaml::Output Output(Stream);
1745   // We use the same mapping method for input and output, so we need a non-const
1746   // reference here.
1747   FormatStyle NonConstStyle = Style;
1748   expandPresetsBraceWrapping(NonConstStyle);
1749   expandPresetsSpaceBeforeParens(NonConstStyle);
1750   Output << NonConstStyle;
1751 
1752   return Stream.str();
1753 }
1754 
1755 llvm::Optional<FormatStyle>
1756 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
1757   if (!Styles)
1758     return None;
1759   auto It = Styles->find(Language);
1760   if (It == Styles->end())
1761     return None;
1762   FormatStyle Style = It->second;
1763   Style.StyleSet = *this;
1764   return Style;
1765 }
1766 
1767 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
1768   assert(Style.Language != LK_None &&
1769          "Cannot add a style for LK_None to a StyleSet");
1770   assert(
1771       !Style.StyleSet.Styles &&
1772       "Cannot add a style associated with an existing StyleSet to a StyleSet");
1773   if (!Styles)
1774     Styles = std::make_shared<MapType>();
1775   (*Styles)[Style.Language] = std::move(Style);
1776 }
1777 
1778 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
1779 
1780 llvm::Optional<FormatStyle>
1781 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
1782   return StyleSet.Get(Language);
1783 }
1784 
1785 namespace {
1786 
1787 class BracesRemover : public TokenAnalyzer {
1788 public:
1789   BracesRemover(const Environment &Env, const FormatStyle &Style)
1790       : TokenAnalyzer(Env, Style) {}
1791 
1792   std::pair<tooling::Replacements, unsigned>
1793   analyze(TokenAnnotator &Annotator,
1794           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1795           FormatTokenLexer &Tokens) override {
1796     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1797     tooling::Replacements Result;
1798     removeBraces(AnnotatedLines, Result);
1799     return {Result, 0};
1800   }
1801 
1802 private:
1803   // Remove optional braces.
1804   void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
1805                     tooling::Replacements &Result) {
1806     const auto &SourceMgr = Env.getSourceManager();
1807     for (AnnotatedLine *Line : Lines) {
1808       removeBraces(Line->Children, Result);
1809       if (!Line->Affected)
1810         continue;
1811       for (FormatToken *Token = Line->First; Token; Token = Token->Next) {
1812         if (!Token->Optional)
1813           continue;
1814         assert(Token->isOneOf(tok::l_brace, tok::r_brace));
1815         const auto Start = Token == Line->Last
1816                                ? Token->WhitespaceRange.getBegin()
1817                                : Token->Tok.getLocation();
1818         const auto Range =
1819             CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());
1820         cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));
1821       }
1822     }
1823   }
1824 };
1825 
1826 class BracesInserter : public TokenAnalyzer {
1827 public:
1828   BracesInserter(const Environment &Env, const FormatStyle &Style)
1829       : TokenAnalyzer(Env, Style) {}
1830 
1831   std::pair<tooling::Replacements, unsigned>
1832   analyze(TokenAnnotator &Annotator,
1833           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1834           FormatTokenLexer &Tokens) override {
1835     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1836     tooling::Replacements Result;
1837     insertBraces(AnnotatedLines, Result);
1838     return {Result, 0};
1839   }
1840 
1841 private:
1842   void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
1843                     tooling::Replacements &Result) {
1844     const auto &SourceMgr = Env.getSourceManager();
1845     for (AnnotatedLine *Line : Lines) {
1846       insertBraces(Line->Children, Result);
1847       if (!Line->Affected)
1848         continue;
1849       for (FormatToken *Token = Line->First; Token && !Token->Finalized;
1850            Token = Token->Next) {
1851         if (Token->BraceCount == 0)
1852           continue;
1853         std::string Brace;
1854         if (Token->BraceCount < 0) {
1855           assert(Token->BraceCount == -1);
1856           Brace = '{';
1857         } else {
1858           Brace = '\n' + std::string(Token->BraceCount, '}');
1859         }
1860         Token->BraceCount = 0;
1861         const auto Start = Token->Tok.getEndLoc();
1862         cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));
1863       }
1864     }
1865   }
1866 };
1867 
1868 class JavaScriptRequoter : public TokenAnalyzer {
1869 public:
1870   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
1871       : TokenAnalyzer(Env, Style) {}
1872 
1873   std::pair<tooling::Replacements, unsigned>
1874   analyze(TokenAnnotator &Annotator,
1875           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1876           FormatTokenLexer &Tokens) override {
1877     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1878     tooling::Replacements Result;
1879     requoteJSStringLiteral(AnnotatedLines, Result);
1880     return {Result, 0};
1881   }
1882 
1883 private:
1884   // Replaces double/single-quoted string literal as appropriate, re-escaping
1885   // the contents in the process.
1886   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
1887                               tooling::Replacements &Result) {
1888     for (AnnotatedLine *Line : Lines) {
1889       requoteJSStringLiteral(Line->Children, Result);
1890       if (!Line->Affected)
1891         continue;
1892       for (FormatToken *FormatTok = Line->First; FormatTok;
1893            FormatTok = FormatTok->Next) {
1894         StringRef Input = FormatTok->TokenText;
1895         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1896             // NB: testing for not starting with a double quote to avoid
1897             // breaking `template strings`.
1898             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
1899              !Input.startswith("\"")) ||
1900             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
1901              !Input.startswith("\'")))
1902           continue;
1903 
1904         // Change start and end quote.
1905         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
1906         SourceLocation Start = FormatTok->Tok.getLocation();
1907         auto Replace = [&](SourceLocation Start, unsigned Length,
1908                            StringRef ReplacementText) {
1909           auto Err = Result.add(tooling::Replacement(
1910               Env.getSourceManager(), Start, Length, ReplacementText));
1911           // FIXME: handle error. For now, print error message and skip the
1912           // replacement for release version.
1913           if (Err) {
1914             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1915             assert(false);
1916           }
1917         };
1918         Replace(Start, 1, IsSingle ? "'" : "\"");
1919         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1920                 IsSingle ? "'" : "\"");
1921 
1922         // Escape internal quotes.
1923         bool Escaped = false;
1924         for (size_t i = 1; i < Input.size() - 1; i++) {
1925           switch (Input[i]) {
1926           case '\\':
1927             if (!Escaped && i + 1 < Input.size() &&
1928                 ((IsSingle && Input[i + 1] == '"') ||
1929                  (!IsSingle && Input[i + 1] == '\''))) {
1930               // Remove this \, it's escaping a " or ' that no longer needs
1931               // escaping
1932               Replace(Start.getLocWithOffset(i), 1, "");
1933               continue;
1934             }
1935             Escaped = !Escaped;
1936             break;
1937           case '\"':
1938           case '\'':
1939             if (!Escaped && IsSingle == (Input[i] == '\'')) {
1940               // Escape the quote.
1941               Replace(Start.getLocWithOffset(i), 0, "\\");
1942             }
1943             Escaped = false;
1944             break;
1945           default:
1946             Escaped = false;
1947             break;
1948           }
1949         }
1950       }
1951     }
1952   }
1953 };
1954 
1955 class Formatter : public TokenAnalyzer {
1956 public:
1957   Formatter(const Environment &Env, const FormatStyle &Style,
1958             FormattingAttemptStatus *Status)
1959       : TokenAnalyzer(Env, Style), Status(Status) {}
1960 
1961   std::pair<tooling::Replacements, unsigned>
1962   analyze(TokenAnnotator &Annotator,
1963           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1964           FormatTokenLexer &Tokens) override {
1965     tooling::Replacements Result;
1966     deriveLocalStyle(AnnotatedLines);
1967     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1968     for (AnnotatedLine *Line : AnnotatedLines)
1969       Annotator.calculateFormattingInformation(*Line);
1970     Annotator.setCommentLineLevels(AnnotatedLines);
1971 
1972     WhitespaceManager Whitespaces(
1973         Env.getSourceManager(), Style,
1974         Style.DeriveLineEnding
1975             ? WhitespaceManager::inputUsesCRLF(
1976                   Env.getSourceManager().getBufferData(Env.getFileID()),
1977                   Style.UseCRLF)
1978             : Style.UseCRLF);
1979     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
1980                                   Env.getSourceManager(), Whitespaces, Encoding,
1981                                   BinPackInconclusiveFunctions);
1982     unsigned Penalty =
1983         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
1984                                Tokens.getKeywords(), Env.getSourceManager(),
1985                                Status)
1986             .format(AnnotatedLines, /*DryRun=*/false,
1987                     /*AdditionalIndent=*/0,
1988                     /*FixBadIndentation=*/false,
1989                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
1990                     /*NextStartColumn=*/Env.getNextStartColumn(),
1991                     /*LastStartColumn=*/Env.getLastStartColumn());
1992     for (const auto &R : Whitespaces.generateReplacements())
1993       if (Result.add(R))
1994         return std::make_pair(Result, 0);
1995     return std::make_pair(Result, Penalty);
1996   }
1997 
1998 private:
1999   bool
2000   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2001     for (const AnnotatedLine *Line : Lines) {
2002       if (hasCpp03IncompatibleFormat(Line->Children))
2003         return true;
2004       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
2005         if (!Tok->hasWhitespaceBefore()) {
2006           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
2007             return true;
2008           if (Tok->is(TT_TemplateCloser) &&
2009               Tok->Previous->is(TT_TemplateCloser))
2010             return true;
2011         }
2012       }
2013     }
2014     return false;
2015   }
2016 
2017   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
2018     int AlignmentDiff = 0;
2019     for (const AnnotatedLine *Line : Lines) {
2020       AlignmentDiff += countVariableAlignments(Line->Children);
2021       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2022         if (!Tok->is(TT_PointerOrReference))
2023           continue;
2024         // Don't treat space in `void foo() &&` as evidence.
2025         if (const auto *Prev = Tok->getPreviousNonComment()) {
2026           if (Prev->is(tok::r_paren) && Prev->MatchingParen)
2027             if (const auto *Func = Prev->MatchingParen->getPreviousNonComment())
2028               if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2029                                 TT_OverloadedOperator))
2030                 continue;
2031         }
2032         bool SpaceBefore = Tok->hasWhitespaceBefore();
2033         bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2034         if (SpaceBefore && !SpaceAfter)
2035           ++AlignmentDiff;
2036         if (!SpaceBefore && SpaceAfter)
2037           --AlignmentDiff;
2038       }
2039     }
2040     return AlignmentDiff;
2041   }
2042 
2043   void
2044   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2045     bool HasBinPackedFunction = false;
2046     bool HasOnePerLineFunction = false;
2047     for (AnnotatedLine *Line : AnnotatedLines) {
2048       if (!Line->First->Next)
2049         continue;
2050       FormatToken *Tok = Line->First->Next;
2051       while (Tok->Next) {
2052         if (Tok->is(PPK_BinPacked))
2053           HasBinPackedFunction = true;
2054         if (Tok->is(PPK_OnePerLine))
2055           HasOnePerLineFunction = true;
2056 
2057         Tok = Tok->Next;
2058       }
2059     }
2060     if (Style.DerivePointerAlignment) {
2061       Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
2062                                    ? FormatStyle::PAS_Left
2063                                    : FormatStyle::PAS_Right;
2064       Style.ReferenceAlignment = FormatStyle::RAS_Pointer;
2065     }
2066     if (Style.Standard == FormatStyle::LS_Auto)
2067       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
2068                            ? FormatStyle::LS_Latest
2069                            : FormatStyle::LS_Cpp03;
2070     BinPackInconclusiveFunctions =
2071         HasBinPackedFunction || !HasOnePerLineFunction;
2072   }
2073 
2074   bool BinPackInconclusiveFunctions;
2075   FormattingAttemptStatus *Status;
2076 };
2077 
2078 /// TrailingCommaInserter inserts trailing commas into container literals.
2079 /// E.g.:
2080 ///     const x = [
2081 ///       1,
2082 ///     ];
2083 /// TrailingCommaInserter runs after formatting. To avoid causing a required
2084 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
2085 /// ColumnLimit.
2086 ///
2087 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
2088 /// is conceptually incompatible with bin packing.
2089 class TrailingCommaInserter : public TokenAnalyzer {
2090 public:
2091   TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
2092       : TokenAnalyzer(Env, Style) {}
2093 
2094   std::pair<tooling::Replacements, unsigned>
2095   analyze(TokenAnnotator &Annotator,
2096           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2097           FormatTokenLexer &Tokens) override {
2098     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2099     tooling::Replacements Result;
2100     insertTrailingCommas(AnnotatedLines, Result);
2101     return {Result, 0};
2102   }
2103 
2104 private:
2105   /// Inserts trailing commas in [] and {} initializers if they wrap over
2106   /// multiple lines.
2107   void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
2108                             tooling::Replacements &Result) {
2109     for (AnnotatedLine *Line : Lines) {
2110       insertTrailingCommas(Line->Children, Result);
2111       if (!Line->Affected)
2112         continue;
2113       for (FormatToken *FormatTok = Line->First; FormatTok;
2114            FormatTok = FormatTok->Next) {
2115         if (FormatTok->NewlinesBefore == 0)
2116           continue;
2117         FormatToken *Matching = FormatTok->MatchingParen;
2118         if (!Matching || !FormatTok->getPreviousNonComment())
2119           continue;
2120         if (!(FormatTok->is(tok::r_square) &&
2121               Matching->is(TT_ArrayInitializerLSquare)) &&
2122             !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral)))
2123           continue;
2124         FormatToken *Prev = FormatTok->getPreviousNonComment();
2125         if (Prev->is(tok::comma) || Prev->is(tok::semi))
2126           continue;
2127         // getEndLoc is not reliably set during re-lexing, use text length
2128         // instead.
2129         SourceLocation Start =
2130             Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
2131         // If inserting a comma would push the code over the column limit, skip
2132         // this location - it'd introduce an unstable formatting due to the
2133         // required reflow.
2134         unsigned ColumnNumber =
2135             Env.getSourceManager().getSpellingColumnNumber(Start);
2136         if (ColumnNumber > Style.ColumnLimit)
2137           continue;
2138         // Comma insertions cannot conflict with each other, and this pass has a
2139         // clean set of Replacements, so the operation below cannot fail.
2140         cantFail(Result.add(
2141             tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
2142       }
2143     }
2144   }
2145 };
2146 
2147 // This class clean up the erroneous/redundant code around the given ranges in
2148 // file.
2149 class Cleaner : public TokenAnalyzer {
2150 public:
2151   Cleaner(const Environment &Env, const FormatStyle &Style)
2152       : TokenAnalyzer(Env, Style),
2153         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
2154 
2155   // FIXME: eliminate unused parameters.
2156   std::pair<tooling::Replacements, unsigned>
2157   analyze(TokenAnnotator &Annotator,
2158           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2159           FormatTokenLexer &Tokens) override {
2160     // FIXME: in the current implementation the granularity of affected range
2161     // is an annotated line. However, this is not sufficient. Furthermore,
2162     // redundant code introduced by replacements does not necessarily
2163     // intercept with ranges of replacements that result in the redundancy.
2164     // To determine if some redundant code is actually introduced by
2165     // replacements(e.g. deletions), we need to come up with a more
2166     // sophisticated way of computing affected ranges.
2167     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
2168 
2169     checkEmptyNamespace(AnnotatedLines);
2170 
2171     for (auto *Line : AnnotatedLines)
2172       cleanupLine(Line);
2173 
2174     return {generateFixes(), 0};
2175   }
2176 
2177 private:
2178   void cleanupLine(AnnotatedLine *Line) {
2179     for (auto *Child : Line->Children)
2180       cleanupLine(Child);
2181 
2182     if (Line->Affected) {
2183       cleanupRight(Line->First, tok::comma, tok::comma);
2184       cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
2185       cleanupRight(Line->First, tok::l_paren, tok::comma);
2186       cleanupLeft(Line->First, tok::comma, tok::r_paren);
2187       cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
2188       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
2189       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
2190     }
2191   }
2192 
2193   bool containsOnlyComments(const AnnotatedLine &Line) {
2194     for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
2195       if (Tok->isNot(tok::comment))
2196         return false;
2197     return true;
2198   }
2199 
2200   // Iterate through all lines and remove any empty (nested) namespaces.
2201   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
2202     std::set<unsigned> DeletedLines;
2203     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
2204       auto &Line = *AnnotatedLines[i];
2205       if (Line.startsWithNamespace())
2206         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
2207     }
2208 
2209     for (auto Line : DeletedLines) {
2210       FormatToken *Tok = AnnotatedLines[Line]->First;
2211       while (Tok) {
2212         deleteToken(Tok);
2213         Tok = Tok->Next;
2214       }
2215     }
2216   }
2217 
2218   // The function checks if the namespace, which starts from \p CurrentLine, and
2219   // its nested namespaces are empty and delete them if they are empty. It also
2220   // sets \p NewLine to the last line checked.
2221   // Returns true if the current namespace is empty.
2222   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2223                            unsigned CurrentLine, unsigned &NewLine,
2224                            std::set<unsigned> &DeletedLines) {
2225     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
2226     if (Style.BraceWrapping.AfterNamespace) {
2227       // If the left brace is in a new line, we should consume it first so that
2228       // it does not make the namespace non-empty.
2229       // FIXME: error handling if there is no left brace.
2230       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
2231         NewLine = CurrentLine;
2232         return false;
2233       }
2234     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
2235       return false;
2236     }
2237     while (++CurrentLine < End) {
2238       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
2239         break;
2240 
2241       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
2242         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
2243                                  DeletedLines))
2244           return false;
2245         CurrentLine = NewLine;
2246         continue;
2247       }
2248 
2249       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
2250         continue;
2251 
2252       // If there is anything other than comments or nested namespaces in the
2253       // current namespace, the namespace cannot be empty.
2254       NewLine = CurrentLine;
2255       return false;
2256     }
2257 
2258     NewLine = CurrentLine;
2259     if (CurrentLine >= End)
2260       return false;
2261 
2262     // Check if the empty namespace is actually affected by changed ranges.
2263     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
2264             AnnotatedLines[InitLine]->First->Tok.getLocation(),
2265             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
2266       return false;
2267 
2268     for (unsigned i = InitLine; i <= CurrentLine; ++i)
2269       DeletedLines.insert(i);
2270 
2271     return true;
2272   }
2273 
2274   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
2275   // of the token in the pair if the left token has \p LK token kind and the
2276   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
2277   // is deleted on match; otherwise, the right token is deleted.
2278   template <typename LeftKind, typename RightKind>
2279   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
2280                    bool DeleteLeft) {
2281     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
2282       for (auto *Res = Tok.Next; Res; Res = Res->Next)
2283         if (!Res->is(tok::comment) &&
2284             DeletedTokens.find(Res) == DeletedTokens.end())
2285           return Res;
2286       return nullptr;
2287     };
2288     for (auto *Left = Start; Left;) {
2289       auto *Right = NextNotDeleted(*Left);
2290       if (!Right)
2291         break;
2292       if (Left->is(LK) && Right->is(RK)) {
2293         deleteToken(DeleteLeft ? Left : Right);
2294         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
2295           deleteToken(Tok);
2296         // If the right token is deleted, we should keep the left token
2297         // unchanged and pair it with the new right token.
2298         if (!DeleteLeft)
2299           continue;
2300       }
2301       Left = Right;
2302     }
2303   }
2304 
2305   template <typename LeftKind, typename RightKind>
2306   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
2307     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
2308   }
2309 
2310   template <typename LeftKind, typename RightKind>
2311   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
2312     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
2313   }
2314 
2315   // Delete the given token.
2316   inline void deleteToken(FormatToken *Tok) {
2317     if (Tok)
2318       DeletedTokens.insert(Tok);
2319   }
2320 
2321   tooling::Replacements generateFixes() {
2322     tooling::Replacements Fixes;
2323     std::vector<FormatToken *> Tokens;
2324     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
2325               std::back_inserter(Tokens));
2326 
2327     // Merge multiple continuous token deletions into one big deletion so that
2328     // the number of replacements can be reduced. This makes computing affected
2329     // ranges more efficient when we run reformat on the changed code.
2330     unsigned Idx = 0;
2331     while (Idx < Tokens.size()) {
2332       unsigned St = Idx, End = Idx;
2333       while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])
2334         ++End;
2335       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2336                                               Tokens[End]->Tok.getEndLoc());
2337       auto Err =
2338           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2339       // FIXME: better error handling. for now just print error message and skip
2340       // for the release version.
2341       if (Err) {
2342         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2343         assert(false && "Fixes must not conflict!");
2344       }
2345       Idx = End + 1;
2346     }
2347 
2348     return Fixes;
2349   }
2350 
2351   // Class for less-than inequality comparason for the set `RedundantTokens`.
2352   // We store tokens in the order they appear in the translation unit so that
2353   // we do not need to sort them in `generateFixes()`.
2354   struct FormatTokenLess {
2355     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2356 
2357     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2358       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2359                                           RHS->Tok.getLocation());
2360     }
2361     const SourceManager &SM;
2362   };
2363 
2364   // Tokens to be deleted.
2365   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2366 };
2367 
2368 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2369 public:
2370   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2371       : TokenAnalyzer(Env, Style), IsObjC(false) {}
2372 
2373   std::pair<tooling::Replacements, unsigned>
2374   analyze(TokenAnnotator &Annotator,
2375           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2376           FormatTokenLexer &Tokens) override {
2377     assert(Style.Language == FormatStyle::LK_Cpp);
2378     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2379                          Tokens.getKeywords());
2380     tooling::Replacements Result;
2381     return {Result, 0};
2382   }
2383 
2384   bool isObjC() { return IsObjC; }
2385 
2386 private:
2387   static bool
2388   guessIsObjC(const SourceManager &SourceManager,
2389               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2390               const AdditionalKeywords &Keywords) {
2391     // Keep this array sorted, since we are binary searching over it.
2392     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2393         "CGFloat",
2394         "CGPoint",
2395         "CGPointMake",
2396         "CGPointZero",
2397         "CGRect",
2398         "CGRectEdge",
2399         "CGRectInfinite",
2400         "CGRectMake",
2401         "CGRectNull",
2402         "CGRectZero",
2403         "CGSize",
2404         "CGSizeMake",
2405         "CGVector",
2406         "CGVectorMake",
2407         "NSAffineTransform",
2408         "NSArray",
2409         "NSAttributedString",
2410         "NSBlockOperation",
2411         "NSBundle",
2412         "NSCache",
2413         "NSCalendar",
2414         "NSCharacterSet",
2415         "NSCountedSet",
2416         "NSData",
2417         "NSDataDetector",
2418         "NSDecimal",
2419         "NSDecimalNumber",
2420         "NSDictionary",
2421         "NSEdgeInsets",
2422         "NSHashTable",
2423         "NSIndexPath",
2424         "NSIndexSet",
2425         "NSInteger",
2426         "NSInvocationOperation",
2427         "NSLocale",
2428         "NSMapTable",
2429         "NSMutableArray",
2430         "NSMutableAttributedString",
2431         "NSMutableCharacterSet",
2432         "NSMutableData",
2433         "NSMutableDictionary",
2434         "NSMutableIndexSet",
2435         "NSMutableOrderedSet",
2436         "NSMutableSet",
2437         "NSMutableString",
2438         "NSNumber",
2439         "NSNumberFormatter",
2440         "NSObject",
2441         "NSOperation",
2442         "NSOperationQueue",
2443         "NSOperationQueuePriority",
2444         "NSOrderedSet",
2445         "NSPoint",
2446         "NSPointerArray",
2447         "NSQualityOfService",
2448         "NSRange",
2449         "NSRect",
2450         "NSRegularExpression",
2451         "NSSet",
2452         "NSSize",
2453         "NSString",
2454         "NSTimeZone",
2455         "NSUInteger",
2456         "NSURL",
2457         "NSURLComponents",
2458         "NSURLQueryItem",
2459         "NSUUID",
2460         "NSValue",
2461         "UIImage",
2462         "UIView",
2463     };
2464 
2465     for (auto Line : AnnotatedLines) {
2466       if (Line->First && (Line->First->TokenText.startswith("#") ||
2467                           Line->First->TokenText == "__pragma" ||
2468                           Line->First->TokenText == "_Pragma"))
2469         continue;
2470       for (const FormatToken *FormatTok = Line->First; FormatTok;
2471            FormatTok = FormatTok->Next) {
2472         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
2473              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
2474               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
2475                                  tok::l_brace))) ||
2476             (FormatTok->Tok.isAnyIdentifier() &&
2477              std::binary_search(std::begin(FoundationIdentifiers),
2478                                 std::end(FoundationIdentifiers),
2479                                 FormatTok->TokenText)) ||
2480             FormatTok->is(TT_ObjCStringLiteral) ||
2481             FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
2482                                Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
2483                                TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
2484                                TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
2485                                TT_ObjCProperty)) {
2486           LLVM_DEBUG(llvm::dbgs()
2487                      << "Detected ObjC at location "
2488                      << FormatTok->Tok.getLocation().printToString(
2489                             SourceManager)
2490                      << " token: " << FormatTok->TokenText << " token type: "
2491                      << getTokenTypeName(FormatTok->getType()) << "\n");
2492           return true;
2493         }
2494         if (guessIsObjC(SourceManager, Line->Children, Keywords))
2495           return true;
2496       }
2497     }
2498     return false;
2499   }
2500 
2501   bool IsObjC;
2502 };
2503 
2504 struct IncludeDirective {
2505   StringRef Filename;
2506   StringRef Text;
2507   unsigned Offset;
2508   int Category;
2509   int Priority;
2510 };
2511 
2512 struct JavaImportDirective {
2513   StringRef Identifier;
2514   StringRef Text;
2515   unsigned Offset;
2516   std::vector<StringRef> AssociatedCommentLines;
2517   bool IsStatic;
2518 };
2519 
2520 } // end anonymous namespace
2521 
2522 // Determines whether 'Ranges' intersects with ('Start', 'End').
2523 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
2524                          unsigned End) {
2525   for (auto Range : Ranges)
2526     if (Range.getOffset() < End &&
2527         Range.getOffset() + Range.getLength() > Start)
2528       return true;
2529   return false;
2530 }
2531 
2532 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
2533 // before sorting/deduplicating. Index is the index of the include under the
2534 // cursor in the original set of includes. If this include has duplicates, it is
2535 // the index of the first of the duplicates as the others are going to be
2536 // removed. OffsetToEOL describes the cursor's position relative to the end of
2537 // its current line.
2538 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
2539 static std::pair<unsigned, unsigned>
2540 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
2541                 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) {
2542   unsigned CursorIndex = UINT_MAX;
2543   unsigned OffsetToEOL = 0;
2544   for (int i = 0, e = Includes.size(); i != e; ++i) {
2545     unsigned Start = Includes[Indices[i]].Offset;
2546     unsigned End = Start + Includes[Indices[i]].Text.size();
2547     if (!(Cursor >= Start && Cursor < End))
2548       continue;
2549     CursorIndex = Indices[i];
2550     OffsetToEOL = End - Cursor;
2551     // Put the cursor on the only remaining #include among the duplicate
2552     // #includes.
2553     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
2554       CursorIndex = i;
2555     break;
2556   }
2557   return std::make_pair(CursorIndex, OffsetToEOL);
2558 }
2559 
2560 // Replace all "\r\n" with "\n".
2561 std::string replaceCRLF(const std::string &Code) {
2562   std::string NewCode;
2563   size_t Pos = 0, LastPos = 0;
2564 
2565   do {
2566     Pos = Code.find("\r\n", LastPos);
2567     if (Pos == LastPos) {
2568       ++LastPos;
2569       continue;
2570     }
2571     if (Pos == std::string::npos) {
2572       NewCode += Code.substr(LastPos);
2573       break;
2574     }
2575     NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
2576     LastPos = Pos + 2;
2577   } while (Pos != std::string::npos);
2578 
2579   return NewCode;
2580 }
2581 
2582 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
2583 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
2584 // source order.
2585 // #include directives with the same text will be deduplicated, and only the
2586 // first #include in the duplicate #includes remains. If the `Cursor` is
2587 // provided and put on a deleted #include, it will be moved to the remaining
2588 // #include in the duplicate #includes.
2589 static void sortCppIncludes(const FormatStyle &Style,
2590                             const SmallVectorImpl<IncludeDirective> &Includes,
2591                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2592                             StringRef Code, tooling::Replacements &Replaces,
2593                             unsigned *Cursor) {
2594   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2595   unsigned IncludesBeginOffset = Includes.front().Offset;
2596   unsigned IncludesEndOffset =
2597       Includes.back().Offset + Includes.back().Text.size();
2598   unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
2599   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
2600     return;
2601   SmallVector<unsigned, 16> Indices =
2602       llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size()));
2603 
2604   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive)
2605     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2606       const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
2607       const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
2608       return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
2609                       Includes[LHSI].Filename) <
2610              std::tie(Includes[RHSI].Priority, RHSFilenameLower,
2611                       Includes[RHSI].Filename);
2612     });
2613   else
2614     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2615       return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
2616              std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
2617     });
2618 
2619   // The index of the include on which the cursor will be put after
2620   // sorting/deduplicating.
2621   unsigned CursorIndex;
2622   // The offset from cursor to the end of line.
2623   unsigned CursorToEOLOffset;
2624   if (Cursor)
2625     std::tie(CursorIndex, CursorToEOLOffset) =
2626         FindCursorIndex(Includes, Indices, *Cursor);
2627 
2628   // Deduplicate #includes.
2629   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2630                             [&](unsigned LHSI, unsigned RHSI) {
2631                               return Includes[LHSI].Text.trim() ==
2632                                      Includes[RHSI].Text.trim();
2633                             }),
2634                 Indices.end());
2635 
2636   int CurrentCategory = Includes.front().Category;
2637 
2638   // If the #includes are out of order, we generate a single replacement fixing
2639   // the entire block. Otherwise, no replacement is generated.
2640   // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
2641   // enough as additional newlines might be added or removed across #include
2642   // blocks. This we handle below by generating the updated #imclude blocks and
2643   // comparing it to the original.
2644   if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) &&
2645       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
2646     return;
2647 
2648   std::string result;
2649   for (unsigned Index : Indices) {
2650     if (!result.empty()) {
2651       result += "\n";
2652       if (Style.IncludeStyle.IncludeBlocks ==
2653               tooling::IncludeStyle::IBS_Regroup &&
2654           CurrentCategory != Includes[Index].Category)
2655         result += "\n";
2656     }
2657     result += Includes[Index].Text;
2658     if (Cursor && CursorIndex == Index)
2659       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
2660     CurrentCategory = Includes[Index].Category;
2661   }
2662 
2663   // If the #includes are out of order, we generate a single replacement fixing
2664   // the entire range of blocks. Otherwise, no replacement is generated.
2665   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2666                                  IncludesBeginOffset, IncludesBlockSize))))
2667     return;
2668 
2669   auto Err = Replaces.add(tooling::Replacement(
2670       FileName, Includes.front().Offset, IncludesBlockSize, result));
2671   // FIXME: better error handling. For now, just skip the replacement for the
2672   // release version.
2673   if (Err) {
2674     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2675     assert(false);
2676   }
2677 }
2678 
2679 namespace {
2680 
2681 const char CppIncludeRegexPattern[] =
2682     R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))";
2683 
2684 } // anonymous namespace
2685 
2686 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
2687                                       ArrayRef<tooling::Range> Ranges,
2688                                       StringRef FileName,
2689                                       tooling::Replacements &Replaces,
2690                                       unsigned *Cursor) {
2691   unsigned Prev = llvm::StringSwitch<size_t>(Code)
2692                       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
2693                       .Default(0);
2694   unsigned SearchFrom = 0;
2695   llvm::Regex IncludeRegex(CppIncludeRegexPattern);
2696   SmallVector<StringRef, 4> Matches;
2697   SmallVector<IncludeDirective, 16> IncludesInBlock;
2698 
2699   // In compiled files, consider the first #include to be the main #include of
2700   // the file if it is not a system #include. This ensures that the header
2701   // doesn't have hidden dependencies
2702   // (http://llvm.org/docs/CodingStandards.html#include-style).
2703   //
2704   // FIXME: Do some validation, e.g. edit distance of the base name, to fix
2705   // cases where the first #include is unlikely to be the main header.
2706   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2707   bool FirstIncludeBlock = true;
2708   bool MainIncludeFound = false;
2709   bool FormattingOff = false;
2710 
2711   // '[' must be the first and '-' the last character inside [...].
2712   llvm::Regex RawStringRegex(
2713       "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");
2714   SmallVector<StringRef, 2> RawStringMatches;
2715   std::string RawStringTermination = ")\"";
2716 
2717   for (;;) {
2718     auto Pos = Code.find('\n', SearchFrom);
2719     StringRef Line =
2720         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2721 
2722     StringRef Trimmed = Line.trim();
2723 
2724     // #includes inside raw string literals need to be ignored.
2725     // or we will sort the contents of the string.
2726     // Skip past until we think we are at the rawstring literal close.
2727     if (RawStringRegex.match(Trimmed, &RawStringMatches)) {
2728       std::string CharSequence = RawStringMatches[1].str();
2729       RawStringTermination = ")" + CharSequence + "\"";
2730       FormattingOff = true;
2731     }
2732 
2733     if (Trimmed.contains(RawStringTermination))
2734       FormattingOff = false;
2735 
2736     if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
2737       FormattingOff = true;
2738     else if (Trimmed == "// clang-format on" ||
2739              Trimmed == "/* clang-format on */")
2740       FormattingOff = false;
2741 
2742     const bool EmptyLineSkipped =
2743         Trimmed.empty() &&
2744         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
2745          Style.IncludeStyle.IncludeBlocks ==
2746              tooling::IncludeStyle::IBS_Regroup);
2747 
2748     bool MergeWithNextLine = Trimmed.endswith("\\");
2749     if (!FormattingOff && !MergeWithNextLine) {
2750       if (IncludeRegex.match(Line, &Matches)) {
2751         StringRef IncludeName = Matches[2];
2752         if (Line.contains("/*") && !Line.contains("*/")) {
2753           // #include with a start of a block comment, but without the end.
2754           // Need to keep all the lines until the end of the comment together.
2755           // FIXME: This is somehow simplified check that probably does not work
2756           // correctly if there are multiple comments on a line.
2757           Pos = Code.find("*/", SearchFrom);
2758           Line = Code.substr(
2759               Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
2760         }
2761         int Category = Categories.getIncludePriority(
2762             IncludeName,
2763             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
2764         int Priority = Categories.getSortIncludePriority(
2765             IncludeName, !MainIncludeFound && FirstIncludeBlock);
2766         if (Category == 0)
2767           MainIncludeFound = true;
2768         IncludesInBlock.push_back(
2769             {IncludeName, Line, Prev, Category, Priority});
2770       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
2771         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
2772                         Replaces, Cursor);
2773         IncludesInBlock.clear();
2774         if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers.
2775           FirstIncludeBlock = true;
2776         else
2777           FirstIncludeBlock = false;
2778       }
2779     }
2780     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2781       break;
2782 
2783     if (!MergeWithNextLine)
2784       Prev = Pos + 1;
2785     SearchFrom = Pos + 1;
2786   }
2787   if (!IncludesInBlock.empty()) {
2788     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
2789                     Cursor);
2790   }
2791   return Replaces;
2792 }
2793 
2794 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
2795 // if the import does not match any given groups.
2796 static unsigned findJavaImportGroup(const FormatStyle &Style,
2797                                     StringRef ImportIdentifier) {
2798   unsigned LongestMatchIndex = UINT_MAX;
2799   unsigned LongestMatchLength = 0;
2800   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
2801     const std::string &GroupPrefix = Style.JavaImportGroups[I];
2802     if (ImportIdentifier.startswith(GroupPrefix) &&
2803         GroupPrefix.length() > LongestMatchLength) {
2804       LongestMatchIndex = I;
2805       LongestMatchLength = GroupPrefix.length();
2806     }
2807   }
2808   return LongestMatchIndex;
2809 }
2810 
2811 // Sorts and deduplicates a block of includes given by 'Imports' based on
2812 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
2813 // Import declarations with the same text will be deduplicated. Between each
2814 // import group, a newline is inserted, and within each import group, a
2815 // lexicographic sort based on ASCII value is performed.
2816 static void sortJavaImports(const FormatStyle &Style,
2817                             const SmallVectorImpl<JavaImportDirective> &Imports,
2818                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2819                             StringRef Code, tooling::Replacements &Replaces) {
2820   unsigned ImportsBeginOffset = Imports.front().Offset;
2821   unsigned ImportsEndOffset =
2822       Imports.back().Offset + Imports.back().Text.size();
2823   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
2824   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
2825     return;
2826 
2827   SmallVector<unsigned, 16> Indices =
2828       llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size()));
2829   SmallVector<unsigned, 16> JavaImportGroups;
2830   JavaImportGroups.reserve(Imports.size());
2831   for (const JavaImportDirective &Import : Imports)
2832     JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
2833 
2834   bool StaticImportAfterNormalImport =
2835       Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
2836   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2837     // Negating IsStatic to push static imports above non-static imports.
2838     return std::make_tuple(!Imports[LHSI].IsStatic ^
2839                                StaticImportAfterNormalImport,
2840                            JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
2841            std::make_tuple(!Imports[RHSI].IsStatic ^
2842                                StaticImportAfterNormalImport,
2843                            JavaImportGroups[RHSI], Imports[RHSI].Identifier);
2844   });
2845 
2846   // Deduplicate imports.
2847   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2848                             [&](unsigned LHSI, unsigned RHSI) {
2849                               return Imports[LHSI].Text == Imports[RHSI].Text;
2850                             }),
2851                 Indices.end());
2852 
2853   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
2854   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
2855 
2856   std::string result;
2857   for (unsigned Index : Indices) {
2858     if (!result.empty()) {
2859       result += "\n";
2860       if (CurrentIsStatic != Imports[Index].IsStatic ||
2861           CurrentImportGroup != JavaImportGroups[Index])
2862         result += "\n";
2863     }
2864     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
2865       result += CommentLine;
2866       result += "\n";
2867     }
2868     result += Imports[Index].Text;
2869     CurrentIsStatic = Imports[Index].IsStatic;
2870     CurrentImportGroup = JavaImportGroups[Index];
2871   }
2872 
2873   // If the imports are out of order, we generate a single replacement fixing
2874   // the entire block. Otherwise, no replacement is generated.
2875   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2876                                  Imports.front().Offset, ImportsBlockSize))))
2877     return;
2878 
2879   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
2880                                                ImportsBlockSize, result));
2881   // FIXME: better error handling. For now, just skip the replacement for the
2882   // release version.
2883   if (Err) {
2884     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2885     assert(false);
2886   }
2887 }
2888 
2889 namespace {
2890 
2891 const char JavaImportRegexPattern[] =
2892     "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
2893 
2894 } // anonymous namespace
2895 
2896 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
2897                                       ArrayRef<tooling::Range> Ranges,
2898                                       StringRef FileName,
2899                                       tooling::Replacements &Replaces) {
2900   unsigned Prev = 0;
2901   unsigned SearchFrom = 0;
2902   llvm::Regex ImportRegex(JavaImportRegexPattern);
2903   SmallVector<StringRef, 4> Matches;
2904   SmallVector<JavaImportDirective, 16> ImportsInBlock;
2905   std::vector<StringRef> AssociatedCommentLines;
2906 
2907   bool FormattingOff = false;
2908 
2909   for (;;) {
2910     auto Pos = Code.find('\n', SearchFrom);
2911     StringRef Line =
2912         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2913 
2914     StringRef Trimmed = Line.trim();
2915     if (Trimmed == "// clang-format off")
2916       FormattingOff = true;
2917     else if (Trimmed == "// clang-format on")
2918       FormattingOff = false;
2919 
2920     if (ImportRegex.match(Line, &Matches)) {
2921       if (FormattingOff) {
2922         // If at least one import line has formatting turned off, turn off
2923         // formatting entirely.
2924         return Replaces;
2925       }
2926       StringRef Static = Matches[1];
2927       StringRef Identifier = Matches[2];
2928       bool IsStatic = false;
2929       if (Static.contains("static"))
2930         IsStatic = true;
2931       ImportsInBlock.push_back(
2932           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
2933       AssociatedCommentLines.clear();
2934     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
2935       // Associating comments within the imports with the nearest import below
2936       AssociatedCommentLines.push_back(Line);
2937     }
2938     Prev = Pos + 1;
2939     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2940       break;
2941     SearchFrom = Pos + 1;
2942   }
2943   if (!ImportsInBlock.empty())
2944     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
2945   return Replaces;
2946 }
2947 
2948 bool isMpegTS(StringRef Code) {
2949   // MPEG transport streams use the ".ts" file extension. clang-format should
2950   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
2951   // 189 bytes - detect that and return.
2952   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
2953 }
2954 
2955 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); }
2956 
2957 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
2958                                    ArrayRef<tooling::Range> Ranges,
2959                                    StringRef FileName, unsigned *Cursor) {
2960   tooling::Replacements Replaces;
2961   if (!Style.SortIncludes || Style.DisableFormat)
2962     return Replaces;
2963   if (isLikelyXml(Code))
2964     return Replaces;
2965   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
2966       isMpegTS(Code))
2967     return Replaces;
2968   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
2969     return sortJavaScriptImports(Style, Code, Ranges, FileName);
2970   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
2971     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
2972   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
2973   return Replaces;
2974 }
2975 
2976 template <typename T>
2977 static llvm::Expected<tooling::Replacements>
2978 processReplacements(T ProcessFunc, StringRef Code,
2979                     const tooling::Replacements &Replaces,
2980                     const FormatStyle &Style) {
2981   if (Replaces.empty())
2982     return tooling::Replacements();
2983 
2984   auto NewCode = applyAllReplacements(Code, Replaces);
2985   if (!NewCode)
2986     return NewCode.takeError();
2987   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
2988   StringRef FileName = Replaces.begin()->getFilePath();
2989 
2990   tooling::Replacements FormatReplaces =
2991       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2992 
2993   return Replaces.merge(FormatReplaces);
2994 }
2995 
2996 llvm::Expected<tooling::Replacements>
2997 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
2998                    const FormatStyle &Style) {
2999   // We need to use lambda function here since there are two versions of
3000   // `sortIncludes`.
3001   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
3002                          std::vector<tooling::Range> Ranges,
3003                          StringRef FileName) -> tooling::Replacements {
3004     return sortIncludes(Style, Code, Ranges, FileName);
3005   };
3006   auto SortedReplaces =
3007       processReplacements(SortIncludes, Code, Replaces, Style);
3008   if (!SortedReplaces)
3009     return SortedReplaces.takeError();
3010 
3011   // We need to use lambda function here since there are two versions of
3012   // `reformat`.
3013   auto Reformat = [](const FormatStyle &Style, StringRef Code,
3014                      std::vector<tooling::Range> Ranges,
3015                      StringRef FileName) -> tooling::Replacements {
3016     return reformat(Style, Code, Ranges, FileName);
3017   };
3018   return processReplacements(Reformat, Code, *SortedReplaces, Style);
3019 }
3020 
3021 namespace {
3022 
3023 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
3024   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
3025          llvm::Regex(CppIncludeRegexPattern)
3026              .match(Replace.getReplacementText());
3027 }
3028 
3029 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
3030   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
3031 }
3032 
3033 // FIXME: insert empty lines between newly created blocks.
3034 tooling::Replacements
3035 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
3036                         const FormatStyle &Style) {
3037   if (!Style.isCpp())
3038     return Replaces;
3039 
3040   tooling::Replacements HeaderInsertions;
3041   std::set<llvm::StringRef> HeadersToDelete;
3042   tooling::Replacements Result;
3043   for (const auto &R : Replaces) {
3044     if (isHeaderInsertion(R)) {
3045       // Replacements from \p Replaces must be conflict-free already, so we can
3046       // simply consume the error.
3047       llvm::consumeError(HeaderInsertions.add(R));
3048     } else if (isHeaderDeletion(R)) {
3049       HeadersToDelete.insert(R.getReplacementText());
3050     } else if (R.getOffset() == UINT_MAX) {
3051       llvm::errs() << "Insertions other than header #include insertion are "
3052                       "not supported! "
3053                    << R.getReplacementText() << "\n";
3054     } else {
3055       llvm::consumeError(Result.add(R));
3056     }
3057   }
3058   if (HeaderInsertions.empty() && HeadersToDelete.empty())
3059     return Replaces;
3060 
3061   StringRef FileName = Replaces.begin()->getFilePath();
3062   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
3063 
3064   for (const auto &Header : HeadersToDelete) {
3065     tooling::Replacements Replaces =
3066         Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
3067     for (const auto &R : Replaces) {
3068       auto Err = Result.add(R);
3069       if (Err) {
3070         // Ignore the deletion on conflict.
3071         llvm::errs() << "Failed to add header deletion replacement for "
3072                      << Header << ": " << llvm::toString(std::move(Err))
3073                      << "\n";
3074       }
3075     }
3076   }
3077 
3078   llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
3079   llvm::SmallVector<StringRef, 4> Matches;
3080   for (const auto &R : HeaderInsertions) {
3081     auto IncludeDirective = R.getReplacementText();
3082     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
3083     assert(Matched && "Header insertion replacement must have replacement text "
3084                       "'#include ...'");
3085     (void)Matched;
3086     auto IncludeName = Matches[2];
3087     auto Replace =
3088         Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"));
3089     if (Replace) {
3090       auto Err = Result.add(*Replace);
3091       if (Err) {
3092         llvm::consumeError(std::move(Err));
3093         unsigned NewOffset =
3094             Result.getShiftedCodePosition(Replace->getOffset());
3095         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
3096                                             Replace->getReplacementText());
3097         Result = Result.merge(tooling::Replacements(Shifted));
3098       }
3099     }
3100   }
3101   return Result;
3102 }
3103 
3104 } // anonymous namespace
3105 
3106 llvm::Expected<tooling::Replacements>
3107 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
3108                           const FormatStyle &Style) {
3109   // We need to use lambda function here since there are two versions of
3110   // `cleanup`.
3111   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
3112                     std::vector<tooling::Range> Ranges,
3113                     StringRef FileName) -> tooling::Replacements {
3114     return cleanup(Style, Code, Ranges, FileName);
3115   };
3116   // Make header insertion replacements insert new headers into correct blocks.
3117   tooling::Replacements NewReplaces =
3118       fixCppIncludeInsertions(Code, Replaces, Style);
3119   return processReplacements(Cleanup, Code, NewReplaces, Style);
3120 }
3121 
3122 namespace internal {
3123 std::pair<tooling::Replacements, unsigned>
3124 reformat(const FormatStyle &Style, StringRef Code,
3125          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
3126          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
3127          FormattingAttemptStatus *Status) {
3128   FormatStyle Expanded = Style;
3129   expandPresetsBraceWrapping(Expanded);
3130   expandPresetsSpaceBeforeParens(Expanded);
3131   switch (Expanded.RequiresClausePosition) {
3132   case FormatStyle::RCPS_SingleLine:
3133   case FormatStyle::RCPS_WithPreceding:
3134     Expanded.IndentRequiresClause = false;
3135     break;
3136   default:
3137     break;
3138   }
3139 
3140   if (Expanded.DisableFormat)
3141     return {tooling::Replacements(), 0};
3142   if (isLikelyXml(Code))
3143     return {tooling::Replacements(), 0};
3144   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
3145     return {tooling::Replacements(), 0};
3146 
3147   // JSON only needs the formatting passing.
3148   if (Style.isJson()) {
3149     std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
3150     auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3151                                  NextStartColumn, LastStartColumn);
3152     if (!Env)
3153       return {};
3154     // Perform the actual formatting pass.
3155     tooling::Replacements Replaces =
3156         Formatter(*Env, Style, Status).process().first;
3157     // add a replacement to remove the "x = " from the result.
3158     if (!Replaces.add(tooling::Replacement(FileName, 0, 4, ""))) {
3159       // apply the reformatting changes and the removal of "x = ".
3160       if (applyAllReplacements(Code, Replaces))
3161         return {Replaces, 0};
3162     }
3163     return {tooling::Replacements(), 0};
3164   }
3165 
3166   typedef std::function<std::pair<tooling::Replacements, unsigned>(
3167       const Environment &)>
3168       AnalyzerPass;
3169   SmallVector<AnalyzerPass, 4> Passes;
3170 
3171   if (Style.isCpp() && Style.QualifierAlignment != FormatStyle::QAS_Leave) {
3172     Passes.emplace_back([&](const Environment &Env) {
3173       return QualifierAlignmentFixer(Env, Expanded, Code, Ranges,
3174                                      FirstStartColumn, NextStartColumn,
3175                                      LastStartColumn, FileName)
3176           .process();
3177     });
3178   }
3179 
3180   if (Style.isCpp() && Style.InsertBraces)
3181     Passes.emplace_back([&](const Environment &Env) {
3182       return BracesInserter(Env, Expanded).process();
3183     });
3184 
3185   if (Style.isCpp() && Style.RemoveBracesLLVM)
3186     Passes.emplace_back([&](const Environment &Env) {
3187       return BracesRemover(Env, Expanded).process();
3188     });
3189 
3190   if (Style.Language == FormatStyle::LK_Cpp) {
3191     if (Style.FixNamespaceComments)
3192       Passes.emplace_back([&](const Environment &Env) {
3193         return NamespaceEndCommentsFixer(Env, Expanded).process();
3194       });
3195 
3196     if (Style.SortUsingDeclarations)
3197       Passes.emplace_back([&](const Environment &Env) {
3198         return UsingDeclarationsSorter(Env, Expanded).process();
3199       });
3200   }
3201 
3202   if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave)
3203     Passes.emplace_back([&](const Environment &Env) {
3204       return DefinitionBlockSeparator(Env, Expanded).process();
3205     });
3206 
3207   if (Style.isJavaScript() && Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
3208     Passes.emplace_back([&](const Environment &Env) {
3209       return JavaScriptRequoter(Env, Expanded).process();
3210     });
3211 
3212   Passes.emplace_back([&](const Environment &Env) {
3213     return Formatter(Env, Expanded, Status).process();
3214   });
3215 
3216   if (Style.isJavaScript() &&
3217       Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped)
3218     Passes.emplace_back([&](const Environment &Env) {
3219       return TrailingCommaInserter(Env, Expanded).process();
3220     });
3221 
3222   auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,
3223                                NextStartColumn, LastStartColumn);
3224   if (!Env)
3225     return {};
3226   llvm::Optional<std::string> CurrentCode = None;
3227   tooling::Replacements Fixes;
3228   unsigned Penalty = 0;
3229   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
3230     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
3231     auto NewCode = applyAllReplacements(
3232         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
3233     if (NewCode) {
3234       Fixes = Fixes.merge(PassFixes.first);
3235       Penalty += PassFixes.second;
3236       if (I + 1 < E) {
3237         CurrentCode = std::move(*NewCode);
3238         Env = Environment::make(
3239             *CurrentCode, FileName,
3240             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
3241             FirstStartColumn, NextStartColumn, LastStartColumn);
3242         if (!Env)
3243           return {};
3244       }
3245     }
3246   }
3247 
3248   return {Fixes, Penalty};
3249 }
3250 } // namespace internal
3251 
3252 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3253                                ArrayRef<tooling::Range> Ranges,
3254                                StringRef FileName,
3255                                FormattingAttemptStatus *Status) {
3256   return internal::reformat(Style, Code, Ranges,
3257                             /*FirstStartColumn=*/0,
3258                             /*NextStartColumn=*/0,
3259                             /*LastStartColumn=*/0, FileName, Status)
3260       .first;
3261 }
3262 
3263 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
3264                               ArrayRef<tooling::Range> Ranges,
3265                               StringRef FileName) {
3266   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
3267   if (Style.Language != FormatStyle::LK_Cpp)
3268     return tooling::Replacements();
3269   auto Env = Environment::make(Code, FileName, Ranges);
3270   if (!Env)
3271     return {};
3272   return Cleaner(*Env, Style).process().first;
3273 }
3274 
3275 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
3276                                ArrayRef<tooling::Range> Ranges,
3277                                StringRef FileName, bool *IncompleteFormat) {
3278   FormattingAttemptStatus Status;
3279   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
3280   if (!Status.FormatComplete)
3281     *IncompleteFormat = true;
3282   return Result;
3283 }
3284 
3285 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
3286                                               StringRef Code,
3287                                               ArrayRef<tooling::Range> Ranges,
3288                                               StringRef FileName) {
3289   auto Env = Environment::make(Code, FileName, Ranges);
3290   if (!Env)
3291     return {};
3292   return NamespaceEndCommentsFixer(*Env, Style).process().first;
3293 }
3294 
3295 tooling::Replacements separateDefinitionBlocks(const FormatStyle &Style,
3296                                                StringRef Code,
3297                                                ArrayRef<tooling::Range> Ranges,
3298                                                StringRef FileName) {
3299   auto Env = Environment::make(Code, FileName, Ranges);
3300   if (!Env)
3301     return {};
3302   return DefinitionBlockSeparator(*Env, Style).process().first;
3303 }
3304 
3305 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
3306                                             StringRef Code,
3307                                             ArrayRef<tooling::Range> Ranges,
3308                                             StringRef FileName) {
3309   auto Env = Environment::make(Code, FileName, Ranges);
3310   if (!Env)
3311     return {};
3312   return UsingDeclarationsSorter(*Env, Style).process().first;
3313 }
3314 
3315 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
3316   LangOptions LangOpts;
3317 
3318   FormatStyle::LanguageStandard LexingStd = Style.Standard;
3319   if (LexingStd == FormatStyle::LS_Auto)
3320     LexingStd = FormatStyle::LS_Latest;
3321   if (LexingStd == FormatStyle::LS_Latest)
3322     LexingStd = FormatStyle::LS_Cpp20;
3323   LangOpts.CPlusPlus = 1;
3324   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
3325   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
3326   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
3327   LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
3328   LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
3329   // Turning on digraphs in standards before C++0x is error-prone, because e.g.
3330   // the sequence "<::" will be unconditionally treated as "[:".
3331   // Cf. Lexer::LexTokenInternal.
3332   LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
3333 
3334   LangOpts.LineComment = 1;
3335   bool AlternativeOperators = Style.isCpp();
3336   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
3337   LangOpts.Bool = 1;
3338   LangOpts.ObjC = 1;
3339   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
3340   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
3341   LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
3342   return LangOpts;
3343 }
3344 
3345 const char *StyleOptionHelpDescription =
3346     "Coding style, currently supports:\n"
3347     "  LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n"
3348     "Use -style=file to load style configuration from\n"
3349     ".clang-format file located in one of the parent\n"
3350     "directories of the source file (or current\n"
3351     "directory for stdin).\n"
3352     "Use -style=file:<format_file_path> to explicitly specify\n"
3353     "the configuration file.\n"
3354     "Use -style=\"{key: value, ...}\" to set specific\n"
3355     "parameters, e.g.:\n"
3356     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
3357 
3358 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
3359   if (FileName.endswith(".java"))
3360     return FormatStyle::LK_Java;
3361   if (FileName.endswith_insensitive(".js") ||
3362       FileName.endswith_insensitive(".mjs") ||
3363       FileName.endswith_insensitive(".ts"))
3364     return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
3365   if (FileName.endswith(".m") || FileName.endswith(".mm"))
3366     return FormatStyle::LK_ObjC;
3367   if (FileName.endswith_insensitive(".proto") ||
3368       FileName.endswith_insensitive(".protodevel"))
3369     return FormatStyle::LK_Proto;
3370   if (FileName.endswith_insensitive(".textpb") ||
3371       FileName.endswith_insensitive(".pb.txt") ||
3372       FileName.endswith_insensitive(".textproto") ||
3373       FileName.endswith_insensitive(".asciipb"))
3374     return FormatStyle::LK_TextProto;
3375   if (FileName.endswith_insensitive(".td"))
3376     return FormatStyle::LK_TableGen;
3377   if (FileName.endswith_insensitive(".cs"))
3378     return FormatStyle::LK_CSharp;
3379   if (FileName.endswith_insensitive(".json"))
3380     return FormatStyle::LK_Json;
3381   return FormatStyle::LK_Cpp;
3382 }
3383 
3384 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
3385   const auto GuessedLanguage = getLanguageByFileName(FileName);
3386   if (GuessedLanguage == FormatStyle::LK_Cpp) {
3387     auto Extension = llvm::sys::path::extension(FileName);
3388     // If there's no file extension (or it's .h), we need to check the contents
3389     // of the code to see if it contains Objective-C.
3390     if (Extension.empty() || Extension == ".h") {
3391       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
3392       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
3393       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
3394       Guesser.process();
3395       if (Guesser.isObjC())
3396         return FormatStyle::LK_ObjC;
3397     }
3398   }
3399   return GuessedLanguage;
3400 }
3401 
3402 const char *DefaultFormatStyle = "file";
3403 
3404 const char *DefaultFallbackStyle = "LLVM";
3405 
3406 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
3407 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
3408                        FormatStyle *Style, bool AllowUnknownOptions) {
3409   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3410       FS->getBufferForFile(ConfigFile.str());
3411   if (auto EC = Text.getError())
3412     return EC;
3413   if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions))
3414     return EC;
3415   return Text;
3416 }
3417 
3418 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
3419                                      StringRef FallbackStyleName,
3420                                      StringRef Code, llvm::vfs::FileSystem *FS,
3421                                      bool AllowUnknownOptions) {
3422   if (!FS)
3423     FS = llvm::vfs::getRealFileSystem().get();
3424   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
3425 
3426   FormatStyle FallbackStyle = getNoStyle();
3427   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
3428     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
3429 
3430   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
3431       ChildFormatTextToApply;
3432 
3433   if (StyleName.startswith("{")) {
3434     // Parse YAML/JSON style from the command line.
3435     StringRef Source = "<command-line>";
3436     if (std::error_code ec =
3437             parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
3438                                AllowUnknownOptions))
3439       return make_string_error("Error parsing -style: " + ec.message());
3440     if (Style.InheritsParentConfig)
3441       ChildFormatTextToApply.emplace_back(
3442           llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
3443     else
3444       return Style;
3445   }
3446 
3447   // User provided clang-format file using -style=file:path/to/format/file.
3448   if (!Style.InheritsParentConfig &&
3449       StyleName.startswith_insensitive("file:")) {
3450     auto ConfigFile = StyleName.substr(5);
3451     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3452         loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
3453     if (auto EC = Text.getError())
3454       return make_string_error("Error reading " + ConfigFile + ": " +
3455                                EC.message());
3456 
3457     LLVM_DEBUG(llvm::dbgs()
3458                << "Using configuration file " << ConfigFile << "\n");
3459 
3460     if (!Style.InheritsParentConfig)
3461       return Style;
3462 
3463     // Search for parent configs starting from the parent directory of
3464     // ConfigFile.
3465     FileName = ConfigFile;
3466     ChildFormatTextToApply.emplace_back(std::move(*Text));
3467   }
3468 
3469   // If the style inherits the parent configuration it is a command line
3470   // configuration, which wants to inherit, so we have to skip the check of the
3471   // StyleName.
3472   if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) {
3473     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
3474       return make_string_error("Invalid value for -style");
3475     if (!Style.InheritsParentConfig)
3476       return Style;
3477   }
3478 
3479   // Reset possible inheritance
3480   Style.InheritsParentConfig = false;
3481 
3482   // Look for .clang-format/_clang-format file in the file's parent directories.
3483   SmallString<128> UnsuitableConfigFiles;
3484   SmallString<128> Path(FileName);
3485   if (std::error_code EC = FS->makeAbsolute(Path))
3486     return make_string_error(EC.message());
3487 
3488   llvm::SmallVector<std::string, 2> FilesToLookFor;
3489   FilesToLookFor.push_back(".clang-format");
3490   FilesToLookFor.push_back("_clang-format");
3491 
3492   auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
3493 
3494   auto applyChildFormatTexts = [&](FormatStyle *Style) {
3495     for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
3496       auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions,
3497                                    dropDiagnosticHandler);
3498       // It was already correctly parsed.
3499       assert(!EC);
3500       static_cast<void>(EC);
3501     }
3502   };
3503 
3504   for (StringRef Directory = Path; !Directory.empty();
3505        Directory = llvm::sys::path::parent_path(Directory)) {
3506 
3507     auto Status = FS->status(Directory);
3508     if (!Status ||
3509         Status->getType() != llvm::sys::fs::file_type::directory_file)
3510       continue;
3511 
3512     for (const auto &F : FilesToLookFor) {
3513       SmallString<128> ConfigFile(Directory);
3514 
3515       llvm::sys::path::append(ConfigFile, F);
3516       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
3517 
3518       Status = FS->status(ConfigFile.str());
3519 
3520       if (Status &&
3521           (Status->getType() == llvm::sys::fs::file_type::regular_file)) {
3522         llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3523             loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
3524         if (auto EC = Text.getError()) {
3525           if (EC == ParseError::Unsuitable) {
3526             if (!UnsuitableConfigFiles.empty())
3527               UnsuitableConfigFiles.append(", ");
3528             UnsuitableConfigFiles.append(ConfigFile);
3529             continue;
3530           }
3531           return make_string_error("Error reading " + ConfigFile + ": " +
3532                                    EC.message());
3533         }
3534         LLVM_DEBUG(llvm::dbgs()
3535                    << "Using configuration file " << ConfigFile << "\n");
3536 
3537         if (!Style.InheritsParentConfig) {
3538           if (ChildFormatTextToApply.empty())
3539             return Style;
3540 
3541           LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
3542           applyChildFormatTexts(&Style);
3543 
3544           return Style;
3545         }
3546 
3547         LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
3548 
3549         // Reset inheritance of style
3550         Style.InheritsParentConfig = false;
3551 
3552         ChildFormatTextToApply.emplace_back(std::move(*Text));
3553 
3554         // Breaking out of the inner loop, since we don't want to parse
3555         // .clang-format AND _clang-format, if both exist. Then we continue the
3556         // inner loop (parent directories) in search for the parent
3557         // configuration.
3558         break;
3559       }
3560     }
3561   }
3562   if (!UnsuitableConfigFiles.empty())
3563     return make_string_error("Configuration file(s) do(es) not support " +
3564                              getLanguageName(Style.Language) + ": " +
3565                              UnsuitableConfigFiles);
3566 
3567   if (!ChildFormatTextToApply.empty()) {
3568     LLVM_DEBUG(llvm::dbgs()
3569                << "Applying child configurations on fallback style\n");
3570     applyChildFormatTexts(&FallbackStyle);
3571   }
3572 
3573   return FallbackStyle;
3574 }
3575 
3576 } // namespace format
3577 } // namespace clang
3578