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 <map>
36 #include <string>
37
38 #include <google/protobuf/stubs/logging.h>
39 #include <google/protobuf/stubs/common.h>
40 #include <google/protobuf/compiler/java/java_context.h>
41 #include <google/protobuf/compiler/java/java_doc_comment.h>
42 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
43 #include <google/protobuf/compiler/java/java_helpers.h>
44 #include <google/protobuf/compiler/java/java_name_resolver.h>
45 #include <google/protobuf/io/printer.h>
46 #include <google/protobuf/wire_format.h>
47 #include <google/protobuf/stubs/strutil.h>
48
49 namespace google {
50 namespace protobuf {
51 namespace compiler {
52 namespace java {
53
54 namespace {
EnableExperimentalRuntimeForLite()55 bool EnableExperimentalRuntimeForLite() {
56 #ifdef PROTOBUF_EXPERIMENT
57 return PROTOBUF_EXPERIMENT;
58 #else // PROTOBUF_EXPERIMENT
59 return false;
60 #endif // !PROTOBUF_EXPERIMENT
61 }
62
SetEnumVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)63 void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
64 int builderBitIndex, const FieldGeneratorInfo* info,
65 ClassNameResolver* name_resolver,
66 std::map<std::string, std::string>* variables) {
67 SetCommonFieldVariables(descriptor, info, variables);
68
69 (*variables)["type"] =
70 name_resolver->GetImmutableClassName(descriptor->enum_type());
71 (*variables)["mutable_type"] =
72 name_resolver->GetMutableClassName(descriptor->enum_type());
73 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
74 (*variables)["default_number"] =
75 StrCat(descriptor->default_value_enum()->number());
76 (*variables)["tag"] = StrCat(
77 static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
78 (*variables)["tag_size"] = StrCat(
79 internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
80 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
81 // by the proto compiler
82 (*variables)["deprecation"] =
83 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
84 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
85
86 if (SupportFieldPresence(descriptor)) {
87 // For singular messages and builders, one bit is used for the hasField bit.
88 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
89
90 // Note that these have a trailing ";".
91 (*variables)["set_has_field_bit_message"] =
92 GenerateSetBit(messageBitIndex) + ";";
93 (*variables)["clear_has_field_bit_message"] =
94 GenerateClearBit(messageBitIndex) + ";";
95
96 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
97 } else {
98 (*variables)["set_has_field_bit_message"] = "";
99 (*variables)["clear_has_field_bit_message"] = "";
100
101 (*variables)["is_field_present_message"] =
102 (*variables)["name"] + "_ != " + (*variables)["default"] +
103 ".getNumber()";
104 }
105
106 (*variables)["get_has_field_bit_from_local"] =
107 GenerateGetBitFromLocal(builderBitIndex);
108 (*variables)["set_has_field_bit_to_local"] =
109 GenerateSetBitToLocal(messageBitIndex);
110
111 if (SupportUnknownEnumValue(descriptor->file())) {
112 (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
113 } else {
114 (*variables)["unknown"] = (*variables)["default"];
115 }
116
117 // We use `x.getClass()` as a null check because it generates less bytecode
118 // than an `if (x == null) { throw ... }` statement.
119 (*variables)["null_check"] = "value.getClass();\n";
120 }
121
122 } // namespace
123
124 // ===================================================================
125
ImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)126 ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator(
127 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
128 : descriptor_(descriptor),
129 messageBitIndex_(messageBitIndex),
130 context_(context),
131 name_resolver_(context->GetNameResolver()) {
132 SetEnumVariables(descriptor, messageBitIndex, 0,
133 context->GetFieldGeneratorInfo(descriptor), name_resolver_,
134 &variables_);
135 }
136
~ImmutableEnumFieldLiteGenerator()137 ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
138
GetNumBitsForMessage() const139 int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
140 return SupportFieldPresence(descriptor_) ? 1 : 0;
141 }
142
GenerateInterfaceMembers(io::Printer * printer) const143 void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
144 io::Printer* printer) const {
145 if (SupportFieldPresence(descriptor_)) {
146 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
147 printer->Print(variables_,
148 "$deprecation$boolean has$capitalized_name$();\n");
149 }
150 if (SupportUnknownEnumValue(descriptor_->file())) {
151 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
152 printer->Print(variables_,
153 "$deprecation$int get$capitalized_name$Value();\n");
154 }
155 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
156 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
157 }
158
GenerateMembers(io::Printer * printer) const159 void ImmutableEnumFieldLiteGenerator::GenerateMembers(
160 io::Printer* printer) const {
161 printer->Print(variables_, "private int $name$_;\n");
162 PrintExtraFieldInfo(variables_, printer);
163 if (SupportFieldPresence(descriptor_)) {
164 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
165 printer->Print(
166 variables_,
167 "@java.lang.Override\n"
168 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
169 " return $get_has_field_bit_message$;\n"
170 "}\n");
171 printer->Annotate("{", "}", descriptor_);
172 }
173 if (SupportUnknownEnumValue(descriptor_->file())) {
174 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
175 printer->Print(
176 variables_,
177 "@java.lang.Override\n"
178 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
179 " return $name$_;\n"
180 "}\n");
181 printer->Annotate("{", "}", descriptor_);
182 }
183 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
184 printer->Print(variables_,
185 "@java.lang.Override\n"
186 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
187 " $type$ result = $type$.forNumber($name$_);\n"
188 " return result == null ? $unknown$ : result;\n"
189 "}\n");
190 printer->Annotate("{", "}", descriptor_);
191
192 // Generate private setters for the builder to proxy into.
193 if (SupportUnknownEnumValue(descriptor_->file())) {
194 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
195 printer->Print(variables_,
196 "private void set$capitalized_name$Value(int value) {\n"
197 " $set_has_field_bit_message$"
198 " $name$_ = value;\n"
199 "}\n");
200 }
201 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
202 printer->Print(variables_,
203 "private void set$capitalized_name$($type$ value) {\n"
204 " $name$_ = value.getNumber();\n"
205 " $set_has_field_bit_message$\n"
206 "}\n");
207 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
208 printer->Print(variables_,
209 "private void clear$capitalized_name$() {\n"
210 " $clear_has_field_bit_message$\n"
211 " $name$_ = $default_number$;\n"
212 "}\n");
213 }
214
GenerateBuilderMembers(io::Printer * printer) const215 void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
216 io::Printer* printer) const {
217 if (SupportFieldPresence(descriptor_)) {
218 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
219 printer->Print(
220 variables_,
221 "@java.lang.Override\n"
222 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
223 " return instance.has$capitalized_name$();\n"
224 "}\n");
225 printer->Annotate("{", "}", descriptor_);
226 }
227 if (SupportUnknownEnumValue(descriptor_->file())) {
228 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
229 printer->Print(
230 variables_,
231 "@java.lang.Override\n"
232 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
233 " return instance.get$capitalized_name$Value();\n"
234 "}\n");
235 printer->Annotate("{", "}", descriptor_);
236 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
237 /* builder */ true);
238 printer->Print(variables_,
239 "$deprecation$public Builder "
240 "${$set$capitalized_name$Value$}$(int value) {\n"
241 " copyOnWrite();\n"
242 " instance.set$capitalized_name$Value(value);\n"
243 " return this;\n"
244 "}\n");
245 printer->Annotate("{", "}", descriptor_);
246 }
247 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
248 printer->Print(variables_,
249 "@java.lang.Override\n"
250 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
251 " return instance.get$capitalized_name$();\n"
252 "}\n");
253 printer->Annotate("{", "}", descriptor_);
254 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
255 /* builder */ true);
256 printer->Print(variables_,
257 "$deprecation$public Builder "
258 "${$set$capitalized_name$$}$($type$ value) {\n"
259 " copyOnWrite();\n"
260 " instance.set$capitalized_name$(value);\n"
261 " return this;\n"
262 "}\n");
263 printer->Annotate("{", "}", descriptor_);
264 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
265 /* builder */ true);
266 printer->Print(
267 variables_,
268 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
269 " copyOnWrite();\n"
270 " instance.clear$capitalized_name$();\n"
271 " return this;\n"
272 "}\n");
273 printer->Annotate("{", "}", descriptor_);
274 }
275
GenerateInitializationCode(io::Printer * printer) const276 void ImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
277 io::Printer* printer) const {
278 if (!IsDefaultValueJavaDefault(descriptor_)) {
279 printer->Print(variables_, "$name$_ = $default_number$;\n");
280 }
281 }
282
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const283 void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
284 io::Printer* printer, std::vector<uint16>* output) const {
285 WriteIntToUtf16CharSequence(descriptor_->number(), output);
286 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
287 output);
288 if (HasHasbit(descriptor_)) {
289 WriteIntToUtf16CharSequence(messageBitIndex_, output);
290 }
291 printer->Print(variables_, "\"$name$_\",\n");
292 if (!SupportUnknownEnumValue((descriptor_))) {
293 PrintEnumVerifierLogic(printer, descriptor_, variables_,
294 /*var_name=*/"$type$",
295 /*terminating_string=*/",\n",
296 /*enforce_lite=*/context_->EnforceLite());
297 }
298 }
299
GetBoxedType() const300 std::string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
301 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
302 }
303
304 // ===================================================================
305
ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)306 ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator(
307 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
308 : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) {
309 const OneofGeneratorInfo* info =
310 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
311 SetCommonOneofVariables(descriptor, info, &variables_);
312 }
313
~ImmutableEnumOneofFieldLiteGenerator()314 ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {}
315
GenerateMembers(io::Printer * printer) const316 void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers(
317 io::Printer* printer) const {
318 PrintExtraFieldInfo(variables_, printer);
319 if (SupportFieldPresence(descriptor_)) {
320 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
321 printer->Print(
322 variables_,
323 "@java.lang.Override\n"
324 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
325 " return $has_oneof_case_message$;\n"
326 "}\n");
327 printer->Annotate("{", "}", descriptor_);
328 }
329 if (SupportUnknownEnumValue(descriptor_->file())) {
330 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
331 printer->Print(
332 variables_,
333 "@java.lang.Override\n"
334 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
335 " if ($has_oneof_case_message$) {\n"
336 " return (java.lang.Integer) $oneof_name$_;\n"
337 " }\n"
338 " return $default_number$;\n"
339 "}\n");
340 printer->Annotate("{", "}", descriptor_);
341 }
342 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
343 printer->Print(variables_,
344 "@java.lang.Override\n"
345 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
346 " if ($has_oneof_case_message$) {\n"
347 " $type$ result = $type$.forNumber((java.lang.Integer) "
348 "$oneof_name$_);\n"
349 " return result == null ? $unknown$ : result;\n"
350 " }\n"
351 " return $default$;\n"
352 "}\n");
353 printer->Annotate("{", "}", descriptor_);
354
355 // Generate private setters for the builder to proxy into.
356 if (SupportUnknownEnumValue(descriptor_->file())) {
357 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
358 printer->Print(variables_,
359 "private void set$capitalized_name$Value(int value) {\n"
360 " $set_oneof_case_message$;\n"
361 " $oneof_name$_ = value;\n"
362 "}\n");
363 }
364 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
365 printer->Print(variables_,
366 "private void set$capitalized_name$($type$ value) {\n"
367 " $oneof_name$_ = value.getNumber();\n"
368 " $set_oneof_case_message$;\n"
369 "}\n");
370 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
371 printer->Print(variables_,
372 "private void clear$capitalized_name$() {\n"
373 " if ($has_oneof_case_message$) {\n"
374 " $clear_oneof_case_message$;\n"
375 " $oneof_name$_ = null;\n"
376 " }\n"
377 "}\n");
378 }
379
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const380 void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo(
381 io::Printer* printer, std::vector<uint16>* output) const {
382 WriteIntToUtf16CharSequence(descriptor_->number(), output);
383 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
384 output);
385 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
386 if (!SupportUnknownEnumValue(descriptor_)) {
387 PrintEnumVerifierLogic(printer, descriptor_, variables_,
388 /*var_name=*/"$type$",
389 /*terminating_string=*/",\n",
390 /*enforce_lite=*/context_->EnforceLite());
391 }
392 }
393
GenerateBuilderMembers(io::Printer * printer) const394 void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers(
395 io::Printer* printer) const {
396 if (SupportFieldPresence(descriptor_)) {
397 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
398 printer->Print(
399 variables_,
400 "@java.lang.Override\n"
401 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
402 " return instance.has$capitalized_name$();\n"
403 "}\n");
404 printer->Annotate("{", "}", descriptor_);
405 }
406 if (SupportUnknownEnumValue(descriptor_->file())) {
407 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
408 printer->Print(
409 variables_,
410 "@java.lang.Override\n"
411 "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
412 " return instance.get$capitalized_name$Value();\n"
413 "}\n");
414 printer->Annotate("{", "}", descriptor_);
415 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
416 /* builder */ true);
417 printer->Print(variables_,
418 "$deprecation$public Builder "
419 "${$set$capitalized_name$Value$}$(int value) {\n"
420 " copyOnWrite();\n"
421 " instance.set$capitalized_name$Value(value);\n"
422 " return this;\n"
423 "}\n");
424 printer->Annotate("{", "}", descriptor_);
425 }
426 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
427 printer->Print(variables_,
428 "@java.lang.Override\n"
429 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
430 " return instance.get$capitalized_name$();\n"
431 "}\n");
432 printer->Annotate("{", "}", descriptor_);
433 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
434 /* builder */ true);
435 printer->Print(variables_,
436 "$deprecation$public Builder "
437 "${$set$capitalized_name$$}$($type$ value) {\n"
438 " copyOnWrite();\n"
439 " instance.set$capitalized_name$(value);\n"
440 " return this;\n"
441 "}\n");
442 printer->Annotate("{", "}", descriptor_);
443 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
444 /* builder */ true);
445 printer->Print(
446 variables_,
447 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
448 " copyOnWrite();\n"
449 " instance.clear$capitalized_name$();\n"
450 " return this;\n"
451 "}\n");
452 printer->Annotate("{", "}", descriptor_);
453 }
454
455 // ===================================================================
456
457 RepeatedImmutableEnumFieldLiteGenerator::
RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)458 RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
459 int messageBitIndex,
460 Context* context)
461 : descriptor_(descriptor),
462 context_(context),
463 name_resolver_(context->GetNameResolver()) {
464 SetEnumVariables(descriptor, messageBitIndex, 0,
465 context->GetFieldGeneratorInfo(descriptor), name_resolver_,
466 &variables_);
467 }
468
469 RepeatedImmutableEnumFieldLiteGenerator::
~RepeatedImmutableEnumFieldLiteGenerator()470 ~RepeatedImmutableEnumFieldLiteGenerator() {}
471
GetNumBitsForMessage() const472 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
473 return 0;
474 }
475
GenerateInterfaceMembers(io::Printer * printer) const476 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
477 io::Printer* printer) const {
478 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
479 printer->Print(
480 variables_,
481 "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
482 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
483 printer->Print(variables_,
484 "$deprecation$int get$capitalized_name$Count();\n");
485 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
486 printer->Print(variables_,
487 "$deprecation$$type$ get$capitalized_name$(int index);\n");
488 if (SupportUnknownEnumValue(descriptor_->file())) {
489 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
490 printer->Print(variables_,
491 "$deprecation$java.util.List<java.lang.Integer>\n"
492 "get$capitalized_name$ValueList();\n");
493 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
494 LIST_INDEXED_GETTER);
495 printer->Print(variables_,
496 "$deprecation$int get$capitalized_name$Value(int index);\n");
497 }
498 }
499
GenerateMembers(io::Printer * printer) const500 void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers(
501 io::Printer* printer) const {
502 printer->Print(
503 variables_,
504 "private com.google.protobuf.Internal.IntList $name$_;\n"
505 "private static final "
506 "com.google.protobuf.Internal.ListAdapter.Converter<\n"
507 " java.lang.Integer, $type$> $name$_converter_ =\n"
508 " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
509 " java.lang.Integer, $type$>() {\n"
510 " @java.lang.Override\n"
511 " public $type$ convert(java.lang.Integer from) {\n"
512 " $type$ result = $type$.forNumber(from);\n"
513 " return result == null ? $unknown$ : result;\n"
514 " }\n"
515 " };\n");
516 PrintExtraFieldInfo(variables_, printer);
517 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
518 printer->Print(
519 variables_,
520 "@java.lang.Override\n"
521 "$deprecation$public java.util.List<$type$> "
522 "${$get$capitalized_name$List$}$() {\n"
523 " return new com.google.protobuf.Internal.ListAdapter<\n"
524 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
525 "}\n");
526 printer->Annotate("{", "}", descriptor_);
527 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
528 printer->Print(
529 variables_,
530 "@java.lang.Override\n"
531 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
532 " return $name$_.size();\n"
533 "}\n");
534 printer->Annotate("{", "}", descriptor_);
535 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
536 printer->Print(
537 variables_,
538 "@java.lang.Override\n"
539 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
540 " return $name$_converter_.convert($name$_.getInt(index));\n"
541 "}\n");
542 printer->Annotate("{", "}", descriptor_);
543 if (SupportUnknownEnumValue(descriptor_->file())) {
544 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
545 printer->Print(variables_,
546 "@java.lang.Override\n"
547 "$deprecation$public java.util.List<java.lang.Integer>\n"
548 "${$get$capitalized_name$ValueList$}$() {\n"
549 " return $name$_;\n"
550 "}\n");
551 printer->Annotate("{", "}", descriptor_);
552 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
553 LIST_INDEXED_GETTER);
554 printer->Print(variables_,
555 "@java.lang.Override\n"
556 "$deprecation$public int "
557 "${$get$capitalized_name$Value$}$(int index) {\n"
558 " return $name$_.getInt(index);\n"
559 "}\n");
560 printer->Annotate("{", "}", descriptor_);
561 }
562
563 if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
564 context_->HasGeneratedMethods(descriptor_->containing_type())) {
565 printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
566 }
567
568 // Generate private setters for the builder to proxy into.
569 printer->Print(
570 variables_,
571 "private void ensure$capitalized_name$IsMutable() {\n"
572 // Use a temporary to avoid a redundant iget-object.
573 " com.google.protobuf.Internal.IntList tmp = $name$_;\n"
574 " if (!tmp.isModifiable()) {\n"
575 " $name$_ =\n"
576 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
577 " }\n"
578 "}\n");
579 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
580 printer->Print(variables_,
581 "private void set$capitalized_name$(\n"
582 " int index, $type$ value) {\n"
583 " $null_check$"
584 " ensure$capitalized_name$IsMutable();\n"
585 " $name$_.setInt(index, value.getNumber());\n"
586 "}\n");
587 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
588 printer->Print(variables_,
589 "private void add$capitalized_name$($type$ value) {\n"
590 " $null_check$"
591 " ensure$capitalized_name$IsMutable();\n"
592 " $name$_.addInt(value.getNumber());\n"
593 "}\n");
594 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
595 printer->Print(variables_,
596 "private void addAll$capitalized_name$(\n"
597 " java.lang.Iterable<? extends $type$> values) {\n"
598 " ensure$capitalized_name$IsMutable();\n"
599 " for ($type$ value : values) {\n"
600 " $name$_.addInt(value.getNumber());\n"
601 " }\n"
602 "}\n");
603 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
604 printer->Print(variables_,
605 "private void clear$capitalized_name$() {\n"
606 " $name$_ = emptyIntList();\n"
607 "}\n");
608
609 if (SupportUnknownEnumValue(descriptor_->file())) {
610 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
611 printer->Print(variables_,
612 "private void set$capitalized_name$Value(\n"
613 " int index, int value) {\n"
614 " ensure$capitalized_name$IsMutable();\n"
615 " $name$_.setInt(index, value);\n"
616 "}\n");
617 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER);
618 printer->Print(variables_,
619 "private void add$capitalized_name$Value(int value) {\n"
620 " ensure$capitalized_name$IsMutable();\n"
621 " $name$_.addInt(value);\n"
622 "}\n");
623 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
624 LIST_MULTI_ADDER);
625 printer->Print(variables_,
626 "private void addAll$capitalized_name$Value(\n"
627 " java.lang.Iterable<java.lang.Integer> values) {\n"
628 " ensure$capitalized_name$IsMutable();\n"
629 " for (int value : values) {\n"
630 " $name$_.addInt(value);\n"
631 " }\n"
632 "}\n");
633 }
634 }
635
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const636 void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
637 io::Printer* printer, std::vector<uint16>* output) const {
638 WriteIntToUtf16CharSequence(descriptor_->number(), output);
639 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
640 output);
641 printer->Print(variables_, "\"$name$_\",\n");
642 if (!SupportUnknownEnumValue(descriptor_->file())) {
643 PrintEnumVerifierLogic(printer, descriptor_, variables_,
644 /*var_name=*/"$type$",
645 /*terminating_string=*/",\n",
646 /*enforce_lite=*/context_->EnforceLite());
647 }
648 }
649
GenerateBuilderMembers(io::Printer * printer) const650 void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
651 io::Printer* printer) const {
652 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
653 printer->Print(variables_,
654 "@java.lang.Override\n"
655 "$deprecation$public java.util.List<$type$> "
656 "${$get$capitalized_name$List$}$() {\n"
657 " return instance.get$capitalized_name$List();\n"
658 "}\n");
659 printer->Annotate("{", "}", descriptor_);
660 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
661 printer->Print(
662 variables_,
663 "@java.lang.Override\n"
664 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
665 " return instance.get$capitalized_name$Count();\n"
666 "}\n");
667 printer->Annotate("{", "}", descriptor_);
668 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
669 printer->Print(
670 variables_,
671 "@java.lang.Override\n"
672 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
673 " return instance.get$capitalized_name$(index);\n"
674 "}\n");
675 printer->Annotate("{", "}", descriptor_);
676 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
677 /* builder */ true);
678 printer->Print(variables_,
679 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
680 " int index, $type$ value) {\n"
681 " copyOnWrite();\n"
682 " instance.set$capitalized_name$(index, value);\n"
683 " return this;\n"
684 "}\n");
685 printer->Annotate("{", "}", descriptor_);
686 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
687 /* builder */ true);
688 printer->Print(variables_,
689 "$deprecation$public Builder "
690 "${$add$capitalized_name$$}$($type$ value) {\n"
691 " copyOnWrite();\n"
692 " instance.add$capitalized_name$(value);\n"
693 " return this;\n"
694 "}\n");
695 printer->Annotate("{", "}", descriptor_);
696 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
697 /* builder */ true);
698 printer->Print(variables_,
699 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
700 " java.lang.Iterable<? extends $type$> values) {\n"
701 " copyOnWrite();\n"
702 " instance.addAll$capitalized_name$(values);"
703 " return this;\n"
704 "}\n");
705 printer->Annotate("{", "}", descriptor_);
706 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
707 /* builder */ true);
708 printer->Print(
709 variables_,
710 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
711 " copyOnWrite();\n"
712 " instance.clear$capitalized_name$();\n"
713 " return this;\n"
714 "}\n");
715 printer->Annotate("{", "}", descriptor_);
716
717 if (SupportUnknownEnumValue(descriptor_->file())) {
718 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
719 printer->Print(variables_,
720 "@java.lang.Override\n"
721 "$deprecation$public java.util.List<java.lang.Integer>\n"
722 "${$get$capitalized_name$ValueList$}$() {\n"
723 " return java.util.Collections.unmodifiableList(\n"
724 " instance.get$capitalized_name$ValueList());\n"
725 "}\n");
726 printer->Annotate("{", "}", descriptor_);
727 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
728 LIST_INDEXED_GETTER);
729 printer->Print(variables_,
730 "@java.lang.Override\n"
731 "$deprecation$public int "
732 "${$get$capitalized_name$Value$}$(int index) {\n"
733 " return instance.get$capitalized_name$Value(index);\n"
734 "}\n");
735 printer->Annotate("{", "}", descriptor_);
736 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
737 LIST_INDEXED_SETTER,
738 /* builder */ true);
739 printer->Print(
740 variables_,
741 "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
742 " int index, int value) {\n"
743 " copyOnWrite();\n"
744 " instance.set$capitalized_name$Value(index, value);\n"
745 " return this;\n"
746 "}\n");
747 printer->Annotate("{", "}", descriptor_);
748 WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
749 /* builder */ true);
750 printer->Print(variables_,
751 "$deprecation$public Builder "
752 "${$add$capitalized_name$Value$}$(int value) {\n"
753 " instance.add$capitalized_name$Value(value);\n"
754 " return this;\n"
755 "}\n");
756 printer->Annotate("{", "}", descriptor_);
757 WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
758 LIST_MULTI_ADDER,
759 /* builder */ true);
760 printer->Print(
761 variables_,
762 "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
763 " java.lang.Iterable<java.lang.Integer> values) {\n"
764 " copyOnWrite();\n"
765 " instance.addAll$capitalized_name$Value(values);\n"
766 " return this;\n"
767 "}\n");
768 printer->Annotate("{", "}", descriptor_);
769 }
770 }
771
GenerateInitializationCode(io::Printer * printer) const772 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
773 io::Printer* printer) const {
774 printer->Print(variables_, "$name$_ = emptyIntList();\n");
775 }
776
GetBoxedType() const777 std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
778 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
779 }
780
781 } // namespace java
782 } // namespace compiler
783 } // namespace protobuf
784 } // namespace google
785