1 /*
2  * Copyright (c) 2009-2021, Google LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of Google LLC nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef UPBC_COMMON_H
29 #define UPBC_COMMON_H
30 
31 #include <vector>
32 
33 #include "absl/strings/str_replace.h"
34 #include "absl/strings/substitute.h"
35 #include "upb/reflection/def.hpp"
36 
37 namespace upbc {
38 
39 class Output {
40  public:
41   template <class... Arg>
operator()42   void operator()(absl::string_view format, const Arg&... arg) {
43     Write(absl::Substitute(format, arg...));
44   }
45 
output()46   absl::string_view output() const { return output_; }
47 
48  private:
Write(absl::string_view data)49   void Write(absl::string_view data) {
50     std::string stripped;
51     if (absl::StartsWith(data, "\n ")) {
52       size_t indent = data.substr(1).find_first_not_of(' ');
53       if (indent != absl::string_view::npos) {
54         // Remove indentation from all lines.
55         auto line_prefix = data.substr(0, indent + 1);
56         // The final line has an extra newline and is indented two less, eg.
57         //    R"cc(
58         //      UPB_INLINE $0 $1_$2(const $1 *msg) {
59         //        return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4;
60         //      }
61         //    )cc",
62         std::string last_line_prefix = std::string(line_prefix);
63         last_line_prefix.resize(last_line_prefix.size() - 2);
64         data.remove_prefix(line_prefix.size());
65         stripped = absl::StrReplaceAll(
66             data, {{line_prefix, "\n"}, {last_line_prefix, "\n"}});
67         data = stripped;
68       }
69     }
70     absl::StrAppend(&output_, data);
71   }
72 
73   std::string output_;
74 };
75 
76 std::string StripExtension(absl::string_view fname);
77 std::string ToCIdent(absl::string_view str);
78 std::string ToPreproc(absl::string_view str);
79 void EmitFileWarning(absl::string_view name, Output& output);
80 std::string MessageName(upb::MessageDefPtr descriptor);
81 std::string FileLayoutName(upb::FileDefPtr file);
82 std::string HeaderFilename(upb::FileDefPtr file);
83 
84 std::string MessageInit(absl::string_view full_name);
85 std::string EnumInit(upb::EnumDefPtr descriptor);
86 
87 }  // namespace upbc
88 
89 #endif  // UPBC_COMMON_H
90