• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2024 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/compiler/cpp/ifndef_guard.h"
9 
10 #include <string>
11 
12 #include "absl/functional/any_invocable.h"
13 #include "absl/log/die_if_null.h"
14 #include "absl/strings/ascii.h"
15 #include "absl/strings/str_cat.h"
16 #include "absl/strings/str_replace.h"
17 #include "absl/strings/string_view.h"
18 #include "absl/strings/substitute.h"
19 #include "google/protobuf/io/printer.h"
20 
21 namespace google {
22 namespace protobuf {
23 namespace compiler {
24 namespace cpp {
25 
26 namespace {
27 
MakeIfdefGuardIdentifier(const absl::string_view header_path)28 std::string MakeIfdefGuardIdentifier(const absl::string_view header_path) {
29   return absl::StrCat(absl::AsciiStrToUpper(absl::StrReplaceAll(header_path,
30                                                                 {
31                                                                     {"/", "_"},
32                                                                     {".", "_"},
33                                                                     {"-", "_"},
34                                                                 })),
35                       "_");
36 }
37 
38 }  // namespace
39 
IfdefGuardPrinter(google::protobuf::io::Printer * const p,const absl::string_view filename)40 IfdefGuardPrinter::IfdefGuardPrinter(google::protobuf::io::Printer* const p,
41                                      const absl::string_view filename)
42     : IfdefGuardPrinter(p, filename, MakeIfdefGuardIdentifier) {}
43 
IfdefGuardPrinter(google::protobuf::io::Printer * const p,const absl::string_view filename,absl::AnyInvocable<std::string (absl::string_view)> make_ifdef_identifier)44 IfdefGuardPrinter::IfdefGuardPrinter(
45     google::protobuf::io::Printer* const p, const absl::string_view filename,
46     absl::AnyInvocable<std::string(absl::string_view)> make_ifdef_identifier)
47     : p_(ABSL_DIE_IF_NULL(p)),
48       ifdef_identifier_(make_ifdef_identifier(filename)) {
49   // We can't use variable substitution, because we don't know what delimiter
50   // to use.
51   p->Print(absl::Substitute(
52       R"(#ifndef $0
53 #define $0
54 
55 )",
56       ifdef_identifier_));
57 }
58 
~IfdefGuardPrinter()59 IfdefGuardPrinter::~IfdefGuardPrinter() {
60   // We can't use variable substitution, because we don't know what delimiter
61   // to use.
62   p_->Print(absl::Substitute(
63       R"(
64 #endif  // $0
65 )",
66       ifdef_identifier_));
67 }
68 
69 }  // namespace cpp
70 }  // namespace compiler
71 }  // namespace protobuf
72 }  // namespace google
73