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