• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "google/protobuf/compiler/java/field_common.h"
2 
3 #include <cstddef>
4 #include <string>
5 
6 #include "absl/strings/str_cat.h"
7 #include "google/protobuf/compiler/java/helpers.h"
8 #include "google/protobuf/compiler/java/names.h"
9 #include "google/protobuf/descriptor.h"
10 
11 namespace google {
12 namespace protobuf {
13 namespace compiler {
14 namespace java {
15 
SetCommonFieldVariables(const FieldDescriptor * descriptor,const FieldGeneratorInfo * info,absl::flat_hash_map<absl::string_view,std::string> * variables)16 void SetCommonFieldVariables(
17     const FieldDescriptor* descriptor, const FieldGeneratorInfo* info,
18     absl::flat_hash_map<absl::string_view, std::string>* variables) {
19   (*variables)["field_name"] = descriptor->name();
20   (*variables)["name"] = info->name;
21   (*variables)["classname"] = descriptor->containing_type()->name();
22   (*variables)["capitalized_name"] = info->capitalized_name;
23   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
24   (*variables)["constant_name"] = FieldConstantName(descriptor);
25   (*variables)["number"] = absl::StrCat(descriptor->number());
26   (*variables)["kt_dsl_builder"] = "_builder";
27   // These variables are placeholders to pick out the beginning and ends of
28   // identifiers for annotations (when doing so with existing variables would
29   // be ambiguous or impossible). They should never be set to anything but the
30   // empty string.
31   (*variables)["{"] = "";
32   (*variables)["}"] = "";
33   (*variables)["kt_name"] = IsForbiddenKotlin(info->name)
34                                 ? absl::StrCat(info->name, "_")
35                                 : info->name;
36   auto kt_property_name = GetKotlinPropertyName(info->capitalized_name);
37   (*variables)["kt_property_name"] = kt_property_name;
38   (*variables)["kt_safe_name"] = IsForbiddenKotlin(kt_property_name)
39                                      ? absl::StrCat("`", kt_property_name, "`")
40                                      : kt_property_name;
41   (*variables)["kt_capitalized_name"] =
42       IsForbiddenKotlin(info->name) ? absl::StrCat(info->capitalized_name, "_")
43                                     : info->capitalized_name;
44   (*variables)["jvm_synthetic"] = JvmSynthetic(info->options.jvm_dsl);
45   if (!descriptor->is_repeated()) {
46     (*variables)["annotation_field_type"] =
47         std::string(FieldTypeName(descriptor->type()));
48   } else if (GetJavaType(descriptor) == JAVATYPE_MESSAGE &&
49              IsMapEntry(descriptor->message_type())) {
50     (*variables)["annotation_field_type"] =
51         absl::StrCat(FieldTypeName(descriptor->type()), "MAP");
52   } else {
53     (*variables)["annotation_field_type"] =
54         absl::StrCat(FieldTypeName(descriptor->type()), "_LIST");
55     if (descriptor->is_packed()) {
56       variables->insert(
57           {"annotation_field_type",
58            absl::StrCat(FieldTypeName(descriptor->type()), "_LIST_PACKED")});
59     }
60   }
61 }
62 
63 // Locale-independent ASCII upper and lower case munging.
IsUpper(char c)64 static bool IsUpper(char c) {
65   return static_cast<unsigned int>(c - 'A') <= 'Z' - 'A';
66 }
67 
ToLower(char c)68 static char ToLower(char c) { return IsUpper(c) ? c - 'A' + 'a' : c; }
69 
GetKotlinPropertyName(std::string capitalized_name)70 std::string GetKotlinPropertyName(std::string capitalized_name) {
71   // Find the first non-capital. If it is the second character, then we just
72   // need to lowercase the first one. Otherwise we need to lowercase everything
73   // up to but not including the last capital, except that if everything is
74   // capitals then everything must be lowercased.
75   std::string kt_property_name = capitalized_name;
76   size_t first_non_capital;
77   for (first_non_capital = 0; first_non_capital < capitalized_name.length() &&
78                               IsUpper(capitalized_name[first_non_capital]);
79        first_non_capital++) {
80   }
81   size_t stop = first_non_capital;
82   if (stop > 1 && stop < capitalized_name.length()) stop--;
83   for (size_t i = 0; i < stop; i++) {
84     kt_property_name[i] = ToLower(kt_property_name[i]);
85   }
86   return kt_property_name;
87 }
88 
SetCommonOneofVariables(const FieldDescriptor * descriptor,const OneofGeneratorInfo * info,absl::flat_hash_map<absl::string_view,std::string> * variables)89 void SetCommonOneofVariables(
90     const FieldDescriptor* descriptor, const OneofGeneratorInfo* info,
91     absl::flat_hash_map<absl::string_view, std::string>* variables) {
92   (*variables)["oneof_name"] = info->name;
93   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
94   (*variables)["oneof_index"] =
95       absl::StrCat(descriptor->containing_oneof()->index());
96   (*variables)["oneof_stored_type"] = GetOneofStoredType(descriptor);
97   (*variables)["set_oneof_case_message"] =
98       absl::StrCat(info->name, "Case_ = ", descriptor->number());
99   (*variables)["clear_oneof_case_message"] =
100       absl::StrCat(info->name, "Case_ = 0");
101   (*variables)["has_oneof_case_message"] =
102       absl::StrCat(info->name, "Case_ == ", descriptor->number());
103 }
104 
PrintExtraFieldInfo(const absl::flat_hash_map<absl::string_view,std::string> & variables,io::Printer * printer)105 void PrintExtraFieldInfo(
106     const absl::flat_hash_map<absl::string_view, std::string>& variables,
107     io::Printer* printer) {
108   auto it = variables.find("disambiguated_reason");
109   if (it != variables.end() && !it->second.empty()) {
110     printer->Print(
111         variables,
112         "// An alternative name is used for field \"$field_name$\" because:\n"
113         "//     $disambiguated_reason$\n");
114   }
115 }
116 
117 }  // namespace java
118 }  // namespace compiler
119 }  // namespace protobuf
120 }  // namespace google
121