1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
36
37 #include <cstdint>
38 #include <map>
39 #include <string>
40
41 #include <google/protobuf/stubs/logging.h>
42 #include <google/protobuf/stubs/common.h>
43 #include <google/protobuf/io/printer.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/stubs/strutil.h>
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_helpers.h>
49 #include <google/protobuf/compiler/java/java_name_resolver.h>
50
51 namespace google {
52 namespace protobuf {
53 namespace compiler {
54 namespace java {
55
56 namespace {
EnableExperimentalRuntimeForLite()57 bool EnableExperimentalRuntimeForLite() {
58 #ifdef PROTOBUF_EXPERIMENT
59 return PROTOBUF_EXPERIMENT;
60 #else // PROTOBUF_EXPERIMENT
61 return false;
62 #endif // !PROTOBUF_EXPERIMENT
63 }
64
SetEnumVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)65 void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
66 int builderBitIndex, const FieldGeneratorInfo* info,
67 ClassNameResolver* name_resolver,
68 std::map<std::string, std::string>* variables) {
69 SetCommonFieldVariables(descriptor, info, variables);
70
71 (*variables)["type"] =
72 name_resolver->GetImmutableClassName(descriptor->enum_type());
73 (*variables)["kt_type"] = (*variables)["type"];
74 (*variables)["mutable_type"] =
75 name_resolver->GetMutableClassName(descriptor->enum_type());
76 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
77 (*variables)["default_number"] =
78 StrCat(descriptor->default_value_enum()->number());
79 (*variables)["tag"] = StrCat(
80 static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor)));
81 (*variables)["tag_size"] = StrCat(
82 internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
83 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
84 // by the proto compiler
85 (*variables)["deprecation"] =
86 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
87 (*variables)["kt_deprecation"] =
88 descriptor->options().deprecated()
89 ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
90 " is deprecated\") "
91 : "";
92 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
93
94 if (HasHasbit(descriptor)) {
95 // For singular messages and builders, one bit is used for the hasField bit.
96 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
97
98 // Note that these have a trailing ";".
99 (*variables)["set_has_field_bit_message"] =
100 GenerateSetBit(messageBitIndex) + ";";
101 (*variables)["clear_has_field_bit_message"] =
102 GenerateClearBit(messageBitIndex) + ";";
103
104 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
105 } else {
106 (*variables)["set_has_field_bit_message"] = "";
107 (*variables)["clear_has_field_bit_message"] = "";
108
109 (*variables)["is_field_present_message"] =
110 (*variables)["name"] + "_ != " + (*variables)["default"] +
111 ".getNumber()";
112 }
113
114 (*variables)["get_has_field_bit_from_local"] =
115 GenerateGetBitFromLocal(builderBitIndex);
116 (*variables)["set_has_field_bit_to_local"] =
117 GenerateSetBitToLocal(messageBitIndex);
118
119 if (SupportUnknownEnumValue(descriptor->file())) {
120 (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
121 } else {
122 (*variables)["unknown"] = (*variables)["default"];
123 }
124
125 // We use `x.getClass()` as a null check because it generates less bytecode
126 // than an `if (x == null) { throw ... }` statement.
127 (*variables)["null_check"] = "value.getClass();\n";
128 }
129
130 } // namespace
131
132 // ===================================================================
133
ImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)134 ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator(
135 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
136 : descriptor_(descriptor),
137 messageBitIndex_(messageBitIndex),
138 context_(context),
139 name_resolver_(context->GetNameResolver()) {
140 SetEnumVariables(descriptor, messageBitIndex, 0,
141 context->GetFieldGeneratorInfo(descriptor), name_resolver_,
142 &variables_);
143 }
144
~ImmutableEnumFieldLiteGenerator()145 ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
146
GetNumBitsForMessage() const147 int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
148 return HasHasbit(descriptor_) ? 1 : 0;
149 }
150
GenerateInterfaceMembers(io::Printer * printer) const151 void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
152 io::Printer* printer) const {
153 if (HasHazzer(descriptor_)) {
154 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
155 printer->Print(variables_,
156 "$deprecation$boolean has$capitalized_name$();\n");
157 }
158 if (SupportUnknownEnumValue(descriptor_->file())) {
159 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
160 printer->Print(variables_,
161 "$deprecation$int get$capitalized_name$Value();\n");
162 }
163 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
164 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
165 }
166
GenerateMembers(io::Printer * printer) const167 void ImmutableEnumFieldLiteGenerator::GenerateMembers(
168 io::Printer* printer) const {
169 printer->Print(variables_, "private int $name$_;\n");
170 PrintExtraFieldInfo(variables_, printer);
171 if (HasHazzer(descriptor_)) {
172 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
173 printer->Print(
174 variables_,
175 "@java.lang.Override\n"
176 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
177 " return $get_has_field_bit_message$;\n"
178 "}\n");
179 printer->Annotate("{", "}", descriptor_);
180 }
181 if (SupportUnknownEnumValue(descriptor_->file())) {
182 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
183 printer->Print(
184 variables_,
185 "@java.lang.Override\n"
186 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
187 " return $name$_;\n"
188 "}\n");
189 printer->Annotate("{", "}", descriptor_);
190 }
191 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
192 printer->Print(variables_,
193 "@java.lang.Override\n"
194 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
195 " $type$ result = $type$.forNumber($name$_);\n"
196 " return result == null ? $unknown$ : result;\n"
197 "}\n");
198 printer->Annotate("{", "}", descriptor_);
199
200 // Generate private setters for the builder to proxy into.
201 if (SupportUnknownEnumValue(descriptor_->file())) {
202 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
203 printer->Print(variables_,
204 "private void set$capitalized_name$Value(int value) {\n"
205 " $set_has_field_bit_message$"
206 " $name$_ = value;\n"
207 "}\n");
208 }
209 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
210 printer->Print(variables_,
211 "private void set$capitalized_name$($type$ value) {\n"
212 " $name$_ = value.getNumber();\n"
213 " $set_has_field_bit_message$\n"
214 "}\n");
215 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
216 printer->Print(variables_,
217 "private void clear$capitalized_name$() {\n"
218 " $clear_has_field_bit_message$\n"
219 " $name$_ = $default_number$;\n"
220 "}\n");
221 }
222
GenerateBuilderMembers(io::Printer * printer) const223 void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
224 io::Printer* printer) const {
225 if (HasHazzer(descriptor_)) {
226 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
227 printer->Print(
228 variables_,
229 "@java.lang.Override\n"
230 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
231 " return instance.has$capitalized_name$();\n"
232 "}\n");
233 printer->Annotate("{", "}", descriptor_);
234 }
235 if (SupportUnknownEnumValue(descriptor_->file())) {
236 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
237 printer->Print(
238 variables_,
239 "@java.lang.Override\n"
240 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
241 " return instance.get$capitalized_name$Value();\n"
242 "}\n");
243 printer->Annotate("{", "}", descriptor_);
244 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
245 /* builder */ true);
246 printer->Print(variables_,
247 "$deprecation$public Builder "
248 "${$set$capitalized_name$Value$}$(int value) {\n"
249 " copyOnWrite();\n"
250 " instance.set$capitalized_name$Value(value);\n"
251 " return this;\n"
252 "}\n");
253 printer->Annotate("{", "}", descriptor_);
254 }
255 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
256 printer->Print(variables_,
257 "@java.lang.Override\n"
258 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
259 " return instance.get$capitalized_name$();\n"
260 "}\n");
261 printer->Annotate("{", "}", descriptor_);
262 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
263 /* builder */ true);
264 printer->Print(variables_,
265 "$deprecation$public Builder "
266 "${$set$capitalized_name$$}$($type$ value) {\n"
267 " copyOnWrite();\n"
268 " instance.set$capitalized_name$(value);\n"
269 " return this;\n"
270 "}\n");
271 printer->Annotate("{", "}", descriptor_);
272 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
273 /* builder */ true);
274 printer->Print(
275 variables_,
276 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
277 " copyOnWrite();\n"
278 " instance.clear$capitalized_name$();\n"
279 " return this;\n"
280 "}\n");
281 printer->Annotate("{", "}", descriptor_);
282 }
283
GenerateKotlinDslMembers(io::Printer * printer) const284 void ImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers(
285 io::Printer* printer) const {
286 WriteFieldDocComment(printer, descriptor_);
287 printer->Print(variables_,
288 "$kt_deprecation$public var $kt_name$: $kt_type$\n"
289 " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
290 " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
291 " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
292 " set(value) {\n"
293 " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
294 " }\n");
295
296 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
297 /* builder */ false);
298 printer->Print(variables_,
299 "public fun ${$clear$kt_capitalized_name$$}$() {\n"
300 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
301 "}\n");
302
303 if (HasHazzer(descriptor_)) {
304 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
305 printer->Print(
306 variables_,
307 "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
308 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
309 "}\n");
310 }
311 }
312
GenerateInitializationCode(io::Printer * printer) const313 void ImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
314 io::Printer* printer) const {
315 if (!IsDefaultValueJavaDefault(descriptor_)) {
316 printer->Print(variables_, "$name$_ = $default_number$;\n");
317 }
318 }
319
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const320 void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
321 io::Printer* printer, std::vector<uint16_t>* output) const {
322 WriteIntToUtf16CharSequence(descriptor_->number(), output);
323 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
324 output);
325 if (HasHasbit(descriptor_)) {
326 WriteIntToUtf16CharSequence(messageBitIndex_, output);
327 }
328 printer->Print(variables_, "\"$name$_\",\n");
329 if (!SupportUnknownEnumValue((descriptor_))) {
330 PrintEnumVerifierLogic(printer, descriptor_, variables_,
331 /*var_name=*/"$type$",
332 /*terminating_string=*/",\n",
333 /*enforce_lite=*/context_->EnforceLite());
334 }
335 }
336
GetBoxedType() const337 std::string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
338 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
339 }
340
341 // ===================================================================
342
ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)343 ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator(
344 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
345 : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) {
346 const OneofGeneratorInfo* info =
347 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
348 SetCommonOneofVariables(descriptor, info, &variables_);
349 }
350
~ImmutableEnumOneofFieldLiteGenerator()351 ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {}
352
GenerateMembers(io::Printer * printer) const353 void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers(
354 io::Printer* printer) const {
355 PrintExtraFieldInfo(variables_, printer);
356 GOOGLE_DCHECK(HasHazzer(descriptor_));
357 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
358 printer->Print(variables_,
359 "@java.lang.Override\n"
360 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
361 " return $has_oneof_case_message$;\n"
362 "}\n");
363 printer->Annotate("{", "}", descriptor_);
364
365 if (SupportUnknownEnumValue(descriptor_->file())) {
366 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
367 printer->Print(
368 variables_,
369 "@java.lang.Override\n"
370 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
371 " if ($has_oneof_case_message$) {\n"
372 " return (java.lang.Integer) $oneof_name$_;\n"
373 " }\n"
374 " return $default_number$;\n"
375 "}\n");
376 printer->Annotate("{", "}", descriptor_);
377 }
378 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
379 printer->Print(variables_,
380 "@java.lang.Override\n"
381 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
382 " if ($has_oneof_case_message$) {\n"
383 " $type$ result = $type$.forNumber((java.lang.Integer) "
384 "$oneof_name$_);\n"
385 " return result == null ? $unknown$ : result;\n"
386 " }\n"
387 " return $default$;\n"
388 "}\n");
389 printer->Annotate("{", "}", descriptor_);
390
391 // Generate private setters for the builder to proxy into.
392 if (SupportUnknownEnumValue(descriptor_->file())) {
393 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
394 printer->Print(variables_,
395 "private void set$capitalized_name$Value(int value) {\n"
396 " $set_oneof_case_message$;\n"
397 " $oneof_name$_ = value;\n"
398 "}\n");
399 }
400 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
401 printer->Print(variables_,
402 "private void set$capitalized_name$($type$ value) {\n"
403 " $oneof_name$_ = value.getNumber();\n"
404 " $set_oneof_case_message$;\n"
405 "}\n");
406 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
407 printer->Print(variables_,
408 "private void clear$capitalized_name$() {\n"
409 " if ($has_oneof_case_message$) {\n"
410 " $clear_oneof_case_message$;\n"
411 " $oneof_name$_ = null;\n"
412 " }\n"
413 "}\n");
414 }
415
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const416 void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo(
417 io::Printer* printer, std::vector<uint16_t>* output) const {
418 WriteIntToUtf16CharSequence(descriptor_->number(), output);
419 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
420 output);
421 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
422 if (!SupportUnknownEnumValue(descriptor_)) {
423 PrintEnumVerifierLogic(printer, descriptor_, variables_,
424 /*var_name=*/"$type$",
425 /*terminating_string=*/",\n",
426 /*enforce_lite=*/context_->EnforceLite());
427 }
428 }
429
GenerateBuilderMembers(io::Printer * printer) const430 void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers(
431 io::Printer* printer) const {
432 GOOGLE_DCHECK(HasHazzer(descriptor_));
433 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
434 printer->Print(variables_,
435 "@java.lang.Override\n"
436 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
437 " return instance.has$capitalized_name$();\n"
438 "}\n");
439 printer->Annotate("{", "}", descriptor_);
440
441 if (SupportUnknownEnumValue(descriptor_->file())) {
442 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
443 printer->Print(
444 variables_,
445 "@java.lang.Override\n"
446 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
447 " return instance.get$capitalized_name$Value();\n"
448 "}\n");
449 printer->Annotate("{", "}", descriptor_);
450 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
451 /* builder */ true);
452 printer->Print(variables_,
453 "$deprecation$public Builder "
454 "${$set$capitalized_name$Value$}$(int value) {\n"
455 " copyOnWrite();\n"
456 " instance.set$capitalized_name$Value(value);\n"
457 " return this;\n"
458 "}\n");
459 printer->Annotate("{", "}", descriptor_);
460 }
461 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
462 printer->Print(variables_,
463 "@java.lang.Override\n"
464 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
465 " return instance.get$capitalized_name$();\n"
466 "}\n");
467 printer->Annotate("{", "}", descriptor_);
468 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
469 /* builder */ true);
470 printer->Print(variables_,
471 "$deprecation$public Builder "
472 "${$set$capitalized_name$$}$($type$ value) {\n"
473 " copyOnWrite();\n"
474 " instance.set$capitalized_name$(value);\n"
475 " return this;\n"
476 "}\n");
477 printer->Annotate("{", "}", descriptor_);
478 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
479 /* builder */ true);
480 printer->Print(
481 variables_,
482 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
483 " copyOnWrite();\n"
484 " instance.clear$capitalized_name$();\n"
485 " return this;\n"
486 "}\n");
487 printer->Annotate("{", "}", descriptor_);
488 }
489
490 // ===================================================================
491
492 RepeatedImmutableEnumFieldLiteGenerator::
RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)493 RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
494 int messageBitIndex,
495 Context* context)
496 : descriptor_(descriptor),
497 context_(context),
498 name_resolver_(context->GetNameResolver()) {
499 SetEnumVariables(descriptor, messageBitIndex, 0,
500 context->GetFieldGeneratorInfo(descriptor), name_resolver_,
501 &variables_);
502 }
503
504 RepeatedImmutableEnumFieldLiteGenerator::
~RepeatedImmutableEnumFieldLiteGenerator()505 ~RepeatedImmutableEnumFieldLiteGenerator() {}
506
GetNumBitsForMessage() const507 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
508 return 0;
509 }
510
GenerateInterfaceMembers(io::Printer * printer) const511 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
512 io::Printer* printer) const {
513 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
514 printer->Print(
515 variables_,
516 "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
517 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
518 printer->Print(variables_,
519 "$deprecation$int get$capitalized_name$Count();\n");
520 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
521 printer->Print(variables_,
522 "$deprecation$$type$ get$capitalized_name$(int index);\n");
523 if (SupportUnknownEnumValue(descriptor_->file())) {
524 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
525 printer->Print(variables_,
526 "$deprecation$java.util.List<java.lang.Integer>\n"
527 "get$capitalized_name$ValueList();\n");
528 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
529 LIST_INDEXED_GETTER);
530 printer->Print(variables_,
531 "$deprecation$int get$capitalized_name$Value(int index);\n");
532 }
533 }
534
GenerateMembers(io::Printer * printer) const535 void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers(
536 io::Printer* printer) const {
537 printer->Print(
538 variables_,
539 "private com.google.protobuf.Internal.IntList $name$_;\n"
540 "private static final "
541 "com.google.protobuf.Internal.ListAdapter.Converter<\n"
542 " java.lang.Integer, $type$> $name$_converter_ =\n"
543 " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
544 " java.lang.Integer, $type$>() {\n"
545 " @java.lang.Override\n"
546 " public $type$ convert(java.lang.Integer from) {\n"
547 " $type$ result = $type$.forNumber(from);\n"
548 " return result == null ? $unknown$ : result;\n"
549 " }\n"
550 " };\n");
551 PrintExtraFieldInfo(variables_, printer);
552 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
553 printer->Print(
554 variables_,
555 "@java.lang.Override\n"
556 "$deprecation$public java.util.List<$type$> "
557 "${$get$capitalized_name$List$}$() {\n"
558 " return new com.google.protobuf.Internal.ListAdapter<\n"
559 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
560 "}\n");
561 printer->Annotate("{", "}", descriptor_);
562 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
563 printer->Print(
564 variables_,
565 "@java.lang.Override\n"
566 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
567 " return $name$_.size();\n"
568 "}\n");
569 printer->Annotate("{", "}", descriptor_);
570 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
571 printer->Print(
572 variables_,
573 // NB: Do not use the "$name$_converter_" field; the usage of generics
574 // (and requisite upcasts to Object) prevent optimizations. Even
575 // without any optimizations, the below code is cheaper because it
576 // avoids boxing an int and a checkcast from the generics.
577 "@java.lang.Override\n"
578 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
579 " $type$ result = $type$.forNumber($name$_.getInt(index));\n"
580 " return result == null ? $unknown$ : result;\n"
581 "}\n");
582 printer->Annotate("{", "}", descriptor_);
583 if (SupportUnknownEnumValue(descriptor_->file())) {
584 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
585 printer->Print(variables_,
586 "@java.lang.Override\n"
587 "$deprecation$public java.util.List<java.lang.Integer>\n"
588 "${$get$capitalized_name$ValueList$}$() {\n"
589 " return $name$_;\n"
590 "}\n");
591 printer->Annotate("{", "}", descriptor_);
592 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
593 LIST_INDEXED_GETTER);
594 printer->Print(variables_,
595 "@java.lang.Override\n"
596 "$deprecation$public int "
597 "${$get$capitalized_name$Value$}$(int index) {\n"
598 " return $name$_.getInt(index);\n"
599 "}\n");
600 printer->Annotate("{", "}", descriptor_);
601 }
602
603 if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
604 context_->HasGeneratedMethods(descriptor_->containing_type())) {
605 printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
606 }
607
608 // Generate private setters for the builder to proxy into.
609 printer->Print(
610 variables_,
611 "private void ensure$capitalized_name$IsMutable() {\n"
612 // Use a temporary to avoid a redundant iget-object.
613 " com.google.protobuf.Internal.IntList tmp = $name$_;\n"
614 " if (!tmp.isModifiable()) {\n"
615 " $name$_ =\n"
616 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
617 " }\n"
618 "}\n");
619 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
620 printer->Print(variables_,
621 "private void set$capitalized_name$(\n"
622 " int index, $type$ value) {\n"
623 " $null_check$"
624 " ensure$capitalized_name$IsMutable();\n"
625 " $name$_.setInt(index, value.getNumber());\n"
626 "}\n");
627 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
628 printer->Print(variables_,
629 "private void add$capitalized_name$($type$ value) {\n"
630 " $null_check$"
631 " ensure$capitalized_name$IsMutable();\n"
632 " $name$_.addInt(value.getNumber());\n"
633 "}\n");
634 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
635 printer->Print(variables_,
636 "private void addAll$capitalized_name$(\n"
637 " java.lang.Iterable<? extends $type$> values) {\n"
638 " ensure$capitalized_name$IsMutable();\n"
639 " for ($type$ value : values) {\n"
640 " $name$_.addInt(value.getNumber());\n"
641 " }\n"
642 "}\n");
643 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
644 printer->Print(variables_,
645 "private void clear$capitalized_name$() {\n"
646 " $name$_ = emptyIntList();\n"
647 "}\n");
648
649 if (SupportUnknownEnumValue(descriptor_->file())) {
650 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
651 printer->Print(variables_,
652 "private void set$capitalized_name$Value(\n"
653 " int index, int value) {\n"
654 " ensure$capitalized_name$IsMutable();\n"
655 " $name$_.setInt(index, value);\n"
656 "}\n");
657 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER);
658 printer->Print(variables_,
659 "private void add$capitalized_name$Value(int value) {\n"
660 " ensure$capitalized_name$IsMutable();\n"
661 " $name$_.addInt(value);\n"
662 "}\n");
663 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
664 LIST_MULTI_ADDER);
665 printer->Print(variables_,
666 "private void addAll$capitalized_name$Value(\n"
667 " java.lang.Iterable<java.lang.Integer> values) {\n"
668 " ensure$capitalized_name$IsMutable();\n"
669 " for (int value : values) {\n"
670 " $name$_.addInt(value);\n"
671 " }\n"
672 "}\n");
673 }
674 }
675
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const676 void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
677 io::Printer* printer, std::vector<uint16_t>* output) const {
678 WriteIntToUtf16CharSequence(descriptor_->number(), output);
679 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
680 output);
681 printer->Print(variables_, "\"$name$_\",\n");
682 if (!SupportUnknownEnumValue(descriptor_->file())) {
683 PrintEnumVerifierLogic(printer, descriptor_, variables_,
684 /*var_name=*/"$type$",
685 /*terminating_string=*/",\n",
686 /*enforce_lite=*/context_->EnforceLite());
687 }
688 }
689
GenerateBuilderMembers(io::Printer * printer) const690 void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
691 io::Printer* printer) const {
692 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
693 printer->Print(variables_,
694 "@java.lang.Override\n"
695 "$deprecation$public java.util.List<$type$> "
696 "${$get$capitalized_name$List$}$() {\n"
697 " return instance.get$capitalized_name$List();\n"
698 "}\n");
699 printer->Annotate("{", "}", descriptor_);
700 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
701 printer->Print(
702 variables_,
703 "@java.lang.Override\n"
704 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
705 " return instance.get$capitalized_name$Count();\n"
706 "}\n");
707 printer->Annotate("{", "}", descriptor_);
708 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
709 printer->Print(
710 variables_,
711 "@java.lang.Override\n"
712 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
713 " return instance.get$capitalized_name$(index);\n"
714 "}\n");
715 printer->Annotate("{", "}", descriptor_);
716 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
717 /* builder */ true);
718 printer->Print(variables_,
719 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
720 " int index, $type$ value) {\n"
721 " copyOnWrite();\n"
722 " instance.set$capitalized_name$(index, value);\n"
723 " return this;\n"
724 "}\n");
725 printer->Annotate("{", "}", descriptor_);
726 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
727 /* builder */ true);
728 printer->Print(variables_,
729 "$deprecation$public Builder "
730 "${$add$capitalized_name$$}$($type$ value) {\n"
731 " copyOnWrite();\n"
732 " instance.add$capitalized_name$(value);\n"
733 " return this;\n"
734 "}\n");
735 printer->Annotate("{", "}", descriptor_);
736 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
737 /* builder */ true);
738 printer->Print(variables_,
739 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
740 " java.lang.Iterable<? extends $type$> values) {\n"
741 " copyOnWrite();\n"
742 " instance.addAll$capitalized_name$(values);"
743 " return this;\n"
744 "}\n");
745 printer->Annotate("{", "}", descriptor_);
746 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
747 /* builder */ true);
748 printer->Print(
749 variables_,
750 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
751 " copyOnWrite();\n"
752 " instance.clear$capitalized_name$();\n"
753 " return this;\n"
754 "}\n");
755 printer->Annotate("{", "}", descriptor_);
756
757 if (SupportUnknownEnumValue(descriptor_->file())) {
758 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
759 printer->Print(variables_,
760 "@java.lang.Override\n"
761 "$deprecation$public java.util.List<java.lang.Integer>\n"
762 "${$get$capitalized_name$ValueList$}$() {\n"
763 " return java.util.Collections.unmodifiableList(\n"
764 " instance.get$capitalized_name$ValueList());\n"
765 "}\n");
766 printer->Annotate("{", "}", descriptor_);
767 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
768 LIST_INDEXED_GETTER);
769 printer->Print(variables_,
770 "@java.lang.Override\n"
771 "$deprecation$public int "
772 "${$get$capitalized_name$Value$}$(int index) {\n"
773 " return instance.get$capitalized_name$Value(index);\n"
774 "}\n");
775 printer->Annotate("{", "}", descriptor_);
776 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
777 LIST_INDEXED_SETTER,
778 /* builder */ true);
779 printer->Print(
780 variables_,
781 "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
782 " int index, int value) {\n"
783 " copyOnWrite();\n"
784 " instance.set$capitalized_name$Value(index, value);\n"
785 " return this;\n"
786 "}\n");
787 printer->Annotate("{", "}", descriptor_);
788 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
789 /* builder */ true);
790 printer->Print(variables_,
791 "$deprecation$public Builder "
792 "${$add$capitalized_name$Value$}$(int value) {\n"
793 " instance.add$capitalized_name$Value(value);\n"
794 " return this;\n"
795 "}\n");
796 printer->Annotate("{", "}", descriptor_);
797 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
798 LIST_MULTI_ADDER,
799 /* builder */ true);
800 printer->Print(
801 variables_,
802 "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
803 " java.lang.Iterable<java.lang.Integer> values) {\n"
804 " copyOnWrite();\n"
805 " instance.addAll$capitalized_name$Value(values);\n"
806 " return this;\n"
807 "}\n");
808 printer->Annotate("{", "}", descriptor_);
809 }
810 }
811
GenerateInitializationCode(io::Printer * printer) const812 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
813 io::Printer* printer) const {
814 printer->Print(variables_, "$name$_ = emptyIntList();\n");
815 }
816
GenerateKotlinDslMembers(io::Printer * printer) const817 void RepeatedImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers(
818 io::Printer* printer) const {
819 printer->Print(
820 variables_,
821 "/**\n"
822 " * An uninstantiable, behaviorless type to represent the field in\n"
823 " * generics.\n"
824 " */\n"
825 "@kotlin.OptIn"
826 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
827 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
828 " : com.google.protobuf.kotlin.DslProxy()\n");
829
830 WriteFieldDocComment(printer, descriptor_);
831 printer->Print(variables_,
832 "$kt_deprecation$ public val $kt_name$: "
833 "com.google.protobuf.kotlin.DslList"
834 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
835 " @kotlin.jvm.JvmSynthetic\n"
836 " get() = com.google.protobuf.kotlin.DslList(\n"
837 " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
838 " )\n");
839
840 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
841 /* builder */ false);
842 printer->Print(variables_,
843 "@kotlin.jvm.JvmSynthetic\n"
844 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
845 "public fun com.google.protobuf.kotlin.DslList"
846 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
847 "add(value: $kt_type$) {\n"
848 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
849 "}");
850
851 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
852 /* builder */ false);
853 printer->Print(variables_,
854 "@kotlin.jvm.JvmSynthetic\n"
855 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
856 "@Suppress(\"NOTHING_TO_INLINE\")\n"
857 "public inline operator fun com.google.protobuf.kotlin.DslList"
858 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
859 "plusAssign(value: $kt_type$) {\n"
860 " add(value)\n"
861 "}");
862
863 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
864 /* builder */ false);
865 printer->Print(variables_,
866 "@kotlin.jvm.JvmSynthetic\n"
867 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
868 "public fun com.google.protobuf.kotlin.DslList"
869 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
870 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
871 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
872 "}");
873
874 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
875 /* builder */ false);
876 printer->Print(
877 variables_,
878 "@kotlin.jvm.JvmSynthetic\n"
879 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
880 "@Suppress(\"NOTHING_TO_INLINE\")\n"
881 "public inline operator fun com.google.protobuf.kotlin.DslList"
882 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
883 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
884 " addAll(values)\n"
885 "}");
886
887 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
888 /* builder */ false);
889 printer->Print(
890 variables_,
891 "@kotlin.jvm.JvmSynthetic\n"
892 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
893 "public operator fun com.google.protobuf.kotlin.DslList"
894 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
895 "set(index: kotlin.Int, value: $kt_type$) {\n"
896 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
897 "}");
898
899 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
900 /* builder */ false);
901 printer->Print(variables_,
902 "@kotlin.jvm.JvmSynthetic\n"
903 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
904 "public fun com.google.protobuf.kotlin.DslList"
905 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
906 "clear() {\n"
907 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
908 "}");
909 }
910
GetBoxedType() const911 std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
912 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
913 }
914
915 } // namespace java
916 } // namespace compiler
917 } // namespace protobuf
918 } // namespace google
919