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