35 #include <google/protobuf/compiler/cpp/cpp_field.h>
41 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
42 #include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
43 #include <google/protobuf/compiler/cpp/cpp_string_field.h>
44 #include <google/protobuf/stubs/strutil.h>
45 #include <google/protobuf/stubs/substitute.h>
46 #include <google/protobuf/stubs/logging.h>
47 #include <google/protobuf/stubs/common.h>
48 #include <google/protobuf/compiler/cpp/cpp_enum_field.h>
49 #include <google/protobuf/compiler/cpp/cpp_map_field.h>
50 #include <google/protobuf/compiler/cpp/cpp_message_field.h>
51 #include <google/protobuf/descriptor.pb.h>
52 #include <google/protobuf/io/printer.h>
53 #include <google/protobuf/wire_format.h>
60 using internal::WireFormat;
64 void MaySetAnnotationVariable(
const Options&
options,
65 StringPiece annotation_name,
66 StringPiece substitute_template_prefix,
67 StringPiece prepared_template,
68 int field_index, StringPiece access_type,
69 std::map<std::string, std::string>* variables) {
70 if (
options.field_listener_options.forbidden_field_listener_events.count(
74 StrCat(substitute_template_prefix, prepared_template,
");\n"),
75 field_index, access_type);
80 StringPiece field_member) {
83 descriptor->options().ctype() == google::protobuf::FieldOptions::STRING
87 if (
descriptor->default_value_string().empty()) {
89 field_pointer,
": nullptr"),
93 if (
descriptor->options().ctype() == google::protobuf::FieldOptions::STRING_PIECE) {
95 field_pointer,
": nullptr"),
100 descriptor->options().ctype() == google::protobuf::FieldOptions::STRING
104 StrCat(
"_internal_has_", field_name,
"() ? ", field_pointer,
" : ",
105 default_value_pointer),
110 StringPiece field_member) {
111 if (
descriptor->default_value_string().empty()) {
112 return StrCat(
"&", field_member);
115 if (
descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) {
117 "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member,
121 return StrCat(
"&", field_member);
128 std::map<std::string, std::string>* variables) {
131 static constexpr
const char* kAccessorsAnnotations[] = {
132 "annotate_add",
"annotate_get",
"annotate_has",
133 "annotate_list",
"annotate_mutable",
"annotate_mutable_list",
134 "annotate_release",
"annotate_set",
"annotate_size",
135 "annotate_clear",
"annotate_add_mutable",
138 (*variables)[kAccessorsAnnotations[
i]] =
"";
140 if (
options.annotate_accessor) {
142 (*variables)[kAccessorsAnnotations[
i]] =
StrCat(
146 if (!
options.field_listener_options.inject_field_listener_events) {
149 if (
descriptor->file()->options().optimize_for() ==
150 google::protobuf::FileOptions::LITE_RUNTIME) {
153 std::string field_member = (*variables)[
"field_member"];
157 field_member =
StrCat(oneof_member->
name(),
"_.", field_member);
159 const std::string proto_ns = (*variables)[
"proto_ns"];
160 const std::string substitute_template_prefix =
" _tracker_.$1<$0>(this, ";
172 prepared_add_template =
175 prepared_template =
"nullptr";
176 prepared_add_template =
"nullptr";
179 prepared_template =
"nullptr";
182 prepared_template =
"nullptr";
185 prepared_template = GenerateTemplateForOneofString(
186 descriptor, (*variables)[
"proto_ns"], field_member);
189 GenerateTemplateForSingleString(
descriptor, field_member);
192 prepared_template =
StrCat(
"&", field_member);
197 prepared_flat_template =
StrCat(
"&", field_member);
199 prepared_flat_template = prepared_template;
202 MaySetAnnotationVariable(
options,
"get", substitute_template_prefix,
203 prepared_template,
descriptor->index(),
"OnGet",
205 MaySetAnnotationVariable(
options,
"set", substitute_template_prefix,
206 prepared_template,
descriptor->index(),
"OnSet",
208 MaySetAnnotationVariable(
options,
"has", substitute_template_prefix,
209 prepared_template,
descriptor->index(),
"OnHas",
211 MaySetAnnotationVariable(
options,
"mutable", substitute_template_prefix,
212 prepared_template,
descriptor->index(),
"OnMutable",
214 MaySetAnnotationVariable(
options,
"release", substitute_template_prefix,
215 prepared_template,
descriptor->index(),
"OnRelease",
217 MaySetAnnotationVariable(
options,
"clear", substitute_template_prefix,
219 "OnClear", variables);
220 MaySetAnnotationVariable(
options,
"size", substitute_template_prefix,
222 "OnSize", variables);
223 MaySetAnnotationVariable(
options,
"list", substitute_template_prefix,
225 "OnList", variables);
226 MaySetAnnotationVariable(
options,
"mutable_list", substitute_template_prefix,
228 "OnMutableList", variables);
229 MaySetAnnotationVariable(
options,
"add", substitute_template_prefix,
230 prepared_add_template,
descriptor->index(),
"OnAdd",
232 MaySetAnnotationVariable(
options,
"add_mutable", substitute_template_prefix,
234 "OnAddMutable", variables);
238 std::map<std::string, std::string>* variables,
249 (*variables)[
"tag_size"] =
StrCat(
253 (*variables)[
"set_hasbit"] =
"";
254 (*variables)[
"clear_hasbit"] =
"";
256 (*variables)[
"set_hasbit_io"] =
259 (*variables)[
"set_hasbit_io"] =
"";
268 (*variables)[
"{"] =
"";
269 (*variables)[
"}"] =
"";
278 "_has_bits_[", has_bit_index / 32,
"] |= 0x",
281 "_has_bits_[", has_bit_index / 32,
"] &= ~0x",
291 "(_inlined_string_donated_[", inlined_string_index / 32,
"] & 0x",
295 StrCat(
"_inlined_string_donated_[", inlined_string_index / 32,
"]");
303 std::map<std::string, std::string>* variables) {
305 (*variables)[
"oneof_name"] =
descriptor->containing_oneof()->name();
306 (*variables)[
"field_member"] =
314 MessageSCCAnalyzer* scc_analyzer)
318 field_generators_[
i].reset(
325 MessageSCCAnalyzer* scc_analyzer) {
332 MessageSCCAnalyzer* scc_analyzer) {
333 FieldGenerator* generator =
339 if (
field->is_repeated()) {
340 switch (
field->cpp_type()) {
342 if (
field->is_map()) {
343 return new MapFieldGenerator(
field,
options, scc_analyzer);
345 return new RepeatedMessageFieldGenerator(
field,
options,
349 return new RepeatedStringFieldGenerator(
field,
options);
353 return new RepeatedPrimitiveFieldGenerator(
field,
options);
355 }
else if (
field->real_containing_oneof()) {
356 switch (
field->cpp_type()) {
358 return new MessageOneofFieldGenerator(
field,
options, scc_analyzer);
364 return new PrimitiveOneofFieldGenerator(
field,
options);
367 switch (
field->cpp_type()) {
369 return new MessageFieldGenerator(
field,
options, scc_analyzer);