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