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/message_field_lite.h> |
36 | |
37 | #include <cstdint> |
38 | #include <map> |
39 | #include <string> |
40 | |
41 | #include <google/protobuf/io/printer.h> |
42 | #include <google/protobuf/wire_format.h> |
43 | #include <google/protobuf/stubs/strutil.h> |
44 | #include <google/protobuf/compiler/java/context.h> |
45 | #include <google/protobuf/compiler/java/doc_comment.h> |
46 | #include <google/protobuf/compiler/java/helpers.h> |
47 | #include <google/protobuf/compiler/java/name_resolver.h> |
48 | |
49 | // Must be last. |
50 | #include <google/protobuf/port_def.inc> |
51 | |
52 | namespace google { |
53 | namespace protobuf { |
54 | namespace compiler { |
55 | namespace java { |
56 | |
57 | namespace { |
58 | |
59 | void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, |
60 | int builderBitIndex, const FieldGeneratorInfo* info, |
61 | ClassNameResolver* name_resolver, |
62 | std::map<std::string, std::string>* variables) { |
63 | SetCommonFieldVariables(descriptor, info, variables); |
64 | |
65 | (*variables)["type" ] = |
66 | name_resolver->GetImmutableClassName(descriptor: descriptor->message_type()); |
67 | (*variables)["kt_type" ] = (*variables)["type" ]; |
68 | (*variables)["mutable_type" ] = |
69 | name_resolver->GetMutableClassName(descriptor: descriptor->message_type()); |
70 | (*variables)["group_or_message" ] = |
71 | (GetType(field: descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" |
72 | : "Message" ; |
73 | // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported |
74 | // by the proto compiler |
75 | (*variables)["deprecation" ] = |
76 | descriptor->options().deprecated() ? "@java.lang.Deprecated " : "" ; |
77 | (*variables)["kt_deprecation" ] = |
78 | descriptor->options().deprecated() |
79 | ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name" ] + |
80 | " is deprecated\") " |
81 | : "" ; |
82 | (*variables)["required" ] = descriptor->is_required() ? "true" : "false" ; |
83 | |
84 | if (HasHasbit(descriptor)) { |
85 | // For singular messages and builders, one bit is used for the hasField bit. |
86 | (*variables)["get_has_field_bit_message" ] = GenerateGetBit(bitIndex: messageBitIndex); |
87 | |
88 | // Note that these have a trailing ";". |
89 | (*variables)["set_has_field_bit_message" ] = |
90 | GenerateSetBit(bitIndex: messageBitIndex) + ";" ; |
91 | (*variables)["clear_has_field_bit_message" ] = |
92 | GenerateClearBit(bitIndex: messageBitIndex) + ";" ; |
93 | |
94 | (*variables)["is_field_present_message" ] = GenerateGetBit(bitIndex: messageBitIndex); |
95 | } else { |
96 | (*variables)["set_has_field_bit_message" ] = "" ; |
97 | (*variables)["clear_has_field_bit_message" ] = "" ; |
98 | |
99 | (*variables)["is_field_present_message" ] = |
100 | (*variables)["name" ] + "_ != null" ; |
101 | } |
102 | |
103 | (*variables)["get_has_field_bit_from_local" ] = |
104 | GenerateGetBitFromLocal(bitIndex: builderBitIndex); |
105 | (*variables)["set_has_field_bit_to_local" ] = |
106 | GenerateSetBitToLocal(bitIndex: messageBitIndex); |
107 | |
108 | // We use `x.getClass()` as a null check because it generates less bytecode |
109 | // than an `if (x == null) { throw ... }` statement. |
110 | (*variables)["null_check" ] = "value.getClass();\n" ; |
111 | } |
112 | |
113 | } // namespace |
114 | |
115 | // =================================================================== |
116 | |
117 | ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator( |
118 | const FieldDescriptor* descriptor, int messageBitIndex, Context* context) |
119 | : descriptor_(descriptor), |
120 | messageBitIndex_(messageBitIndex), |
121 | name_resolver_(context->GetNameResolver()) { |
122 | SetMessageVariables(descriptor, messageBitIndex, builderBitIndex: 0, |
123 | info: context->GetFieldGeneratorInfo(field: descriptor), |
124 | name_resolver: name_resolver_, variables: &variables_); |
125 | } |
126 | |
127 | ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {} |
128 | |
129 | int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { |
130 | // TODO(dweis): We don't need a has bit for messages as they have null |
131 | // sentinels and no user should be reflecting on this. We could save some |
132 | // bits by setting to 0 and updating the runtimes but this might come at a |
133 | // runtime performance cost since we can't memoize has-bit reads. |
134 | return HasHasbit(descriptor: descriptor_) ? 1 : 0; |
135 | } |
136 | |
137 | void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers( |
138 | io::Printer* printer) const { |
139 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); |
140 | printer->Print(variables: variables_, text: "$deprecation$boolean has$capitalized_name$();\n" ); |
141 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); |
142 | printer->Print(variables: variables_, text: "$deprecation$$type$ get$capitalized_name$();\n" ); |
143 | } |
144 | |
145 | void ImmutableMessageFieldLiteGenerator::GenerateMembers( |
146 | io::Printer* printer) const { |
147 | |
148 | printer->Print(variables: variables_, text: "private $type$ $name$_;\n" ); |
149 | PrintExtraFieldInfo(variables: variables_, printer); |
150 | |
151 | if (HasHasbit(descriptor: descriptor_)) { |
152 | WriteFieldDocComment(printer, field: descriptor_); |
153 | printer->Print( |
154 | variables: variables_, |
155 | text: "@java.lang.Override\n" |
156 | "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" |
157 | " return $get_has_field_bit_message$;\n" |
158 | "}\n" ); |
159 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
160 | WriteFieldDocComment(printer, field: descriptor_); |
161 | printer->Print( |
162 | variables: variables_, |
163 | text: "@java.lang.Override\n" |
164 | "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" |
165 | " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" |
166 | "}\n" ); |
167 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
168 | } else { |
169 | WriteFieldDocComment(printer, field: descriptor_); |
170 | printer->Print( |
171 | variables: variables_, |
172 | text: "@java.lang.Override\n" |
173 | "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" |
174 | " return $name$_ != null;\n" |
175 | "}\n" ); |
176 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
177 | WriteFieldDocComment(printer, field: descriptor_); |
178 | printer->Print( |
179 | variables: variables_, |
180 | text: "@java.lang.Override\n" |
181 | "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" |
182 | " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" |
183 | "}\n" ); |
184 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
185 | } |
186 | |
187 | // Field.Builder setField(Field value) |
188 | WriteFieldDocComment(printer, field: descriptor_); |
189 | printer->Print(variables: variables_, |
190 | text: "private void set$capitalized_name$($type$ value) {\n" |
191 | " $null_check$" |
192 | " $name$_ = value;\n" |
193 | " $set_has_field_bit_message$\n" |
194 | " }\n" ); |
195 | |
196 | // Field.Builder mergeField(Field value) |
197 | WriteFieldDocComment(printer, field: descriptor_); |
198 | printer->Print( |
199 | variables: variables_, |
200 | text: "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n" |
201 | "private void merge$capitalized_name$($type$ value) {\n" |
202 | " $null_check$" |
203 | " if ($name$_ != null &&\n" |
204 | " $name$_ != $type$.getDefaultInstance()) {\n" |
205 | " $name$_ =\n" |
206 | " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" |
207 | " } else {\n" |
208 | " $name$_ = value;\n" |
209 | " }\n" |
210 | " $set_has_field_bit_message$\n" |
211 | "}\n" ); |
212 | |
213 | // Field.Builder clearField() |
214 | WriteFieldDocComment(printer, field: descriptor_); |
215 | printer->Print(variables: variables_, |
216 | text: "private void clear$capitalized_name$() {" |
217 | " $name$_ = null;\n" |
218 | " $clear_has_field_bit_message$\n" |
219 | "}\n" ); |
220 | } |
221 | |
222 | void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers( |
223 | io::Printer* printer) const { |
224 | // The comments above the methods below are based on a hypothetical |
225 | // field of type "Field" called "Field". |
226 | |
227 | // boolean hasField() |
228 | WriteFieldDocComment(printer, field: descriptor_); |
229 | printer->Print(variables: variables_, |
230 | text: "@java.lang.Override\n" |
231 | "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" |
232 | " return instance.has$capitalized_name$();\n" |
233 | "}\n" ); |
234 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
235 | |
236 | // Field getField() |
237 | WriteFieldDocComment(printer, field: descriptor_); |
238 | printer->Print(variables: variables_, |
239 | text: "@java.lang.Override\n" |
240 | "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" |
241 | " return instance.get$capitalized_name$();\n" |
242 | "}\n" ); |
243 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
244 | |
245 | // Field.Builder setField(Field value) |
246 | WriteFieldDocComment(printer, field: descriptor_); |
247 | printer->Print(variables: variables_, |
248 | text: "$deprecation$public Builder " |
249 | "${$set$capitalized_name$$}$($type$ value) {\n" |
250 | " copyOnWrite();\n" |
251 | " instance.set$capitalized_name$(value);\n" |
252 | " return this;\n" |
253 | " }\n" ); |
254 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
255 | |
256 | // Field.Builder setField(Field.Builder builderForValue) |
257 | WriteFieldDocComment(printer, field: descriptor_); |
258 | printer->Print(variables: variables_, |
259 | text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" |
260 | " $type$.Builder builderForValue) {\n" |
261 | " copyOnWrite();\n" |
262 | " instance.set$capitalized_name$(builderForValue.build());\n" |
263 | " return this;\n" |
264 | "}\n" ); |
265 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
266 | |
267 | // Field.Builder mergeField(Field value) |
268 | WriteFieldDocComment(printer, field: descriptor_); |
269 | printer->Print(variables: variables_, |
270 | text: "$deprecation$public Builder " |
271 | "${$merge$capitalized_name$$}$($type$ value) {\n" |
272 | " copyOnWrite();\n" |
273 | " instance.merge$capitalized_name$(value);\n" |
274 | " return this;\n" |
275 | "}\n" ); |
276 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
277 | |
278 | // Field.Builder clearField() |
279 | WriteFieldDocComment(printer, field: descriptor_); |
280 | printer->Print(variables: variables_, |
281 | text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {" |
282 | " copyOnWrite();\n" |
283 | " instance.clear$capitalized_name$();\n" |
284 | " return this;\n" |
285 | "}\n" ); |
286 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
287 | } |
288 | |
289 | void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( |
290 | io::Printer* printer) const { |
291 | WriteFieldDocComment(printer, field: descriptor_); |
292 | printer->Print(variables: variables_, |
293 | text: "$kt_deprecation$var $kt_name$: $kt_type$\n" |
294 | " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" |
295 | " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" |
296 | " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" |
297 | " set(value) {\n" |
298 | " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" |
299 | " }\n" ); |
300 | |
301 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, |
302 | /* builder */ false); |
303 | printer->Print(variables: variables_, |
304 | text: "fun ${$clear$kt_capitalized_name$$}$() {\n" |
305 | " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" |
306 | "}\n" ); |
307 | |
308 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); |
309 | printer->Print( |
310 | variables: variables_, |
311 | text: "fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" |
312 | " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" |
313 | "}\n" ); |
314 | GenerateKotlinOrNull(printer); |
315 | } |
316 | |
317 | void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { |
318 | if (descriptor_->has_optional_keyword()) { |
319 | printer->Print(variables: variables_, |
320 | text: "val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" |
321 | " get() = $kt_dsl_builder$.$name$OrNull\n" ); |
322 | } |
323 | } |
324 | |
325 | void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( |
326 | io::Printer* printer, std::vector<uint16_t>* output) const { |
327 | WriteIntToUtf16CharSequence(value: descriptor_->number(), output); |
328 | WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_), |
329 | output); |
330 | if (HasHasbit(descriptor: descriptor_)) { |
331 | WriteIntToUtf16CharSequence(value: messageBitIndex_, output); |
332 | } |
333 | printer->Print(variables: variables_, text: "\"$name$_\",\n" ); |
334 | } |
335 | |
336 | void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode( |
337 | io::Printer* printer) const {} |
338 | |
339 | std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const { |
340 | return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type()); |
341 | } |
342 | |
343 | // =================================================================== |
344 | |
345 | ImmutableMessageOneofFieldLiteGenerator:: |
346 | ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, |
347 | int messageBitIndex, |
348 | Context* context) |
349 | : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) { |
350 | const OneofGeneratorInfo* info = |
351 | context->GetOneofGeneratorInfo(oneof: descriptor->containing_oneof()); |
352 | SetCommonOneofVariables(descriptor, info, variables: &variables_); |
353 | } |
354 | |
355 | ImmutableMessageOneofFieldLiteGenerator:: |
356 | ~ImmutableMessageOneofFieldLiteGenerator() {} |
357 | |
358 | void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers( |
359 | io::Printer* printer) const { |
360 | PrintExtraFieldInfo(variables: variables_, printer); |
361 | WriteFieldDocComment(printer, field: descriptor_); |
362 | printer->Print(variables: variables_, |
363 | text: "@java.lang.Override\n" |
364 | "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" |
365 | " return $has_oneof_case_message$;\n" |
366 | "}\n" ); |
367 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
368 | WriteFieldDocComment(printer, field: descriptor_); |
369 | printer->Print(variables: variables_, |
370 | text: "@java.lang.Override\n" |
371 | "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" |
372 | " if ($has_oneof_case_message$) {\n" |
373 | " return ($type$) $oneof_name$_;\n" |
374 | " }\n" |
375 | " return $type$.getDefaultInstance();\n" |
376 | "}\n" ); |
377 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
378 | |
379 | // Field.Builder setField(Field value) |
380 | WriteFieldDocComment(printer, field: descriptor_); |
381 | printer->Print(variables: variables_, |
382 | text: "private void set$capitalized_name$($type$ value) {\n" |
383 | " $null_check$" |
384 | " $oneof_name$_ = value;\n" |
385 | " $set_oneof_case_message$;\n" |
386 | "}\n" ); |
387 | |
388 | // Field.Builder mergeField(Field value) |
389 | WriteFieldDocComment(printer, field: descriptor_); |
390 | printer->Print( |
391 | variables: variables_, |
392 | text: "private void merge$capitalized_name$($type$ value) {\n" |
393 | " $null_check$" |
394 | " if ($has_oneof_case_message$ &&\n" |
395 | " $oneof_name$_ != $type$.getDefaultInstance()) {\n" |
396 | " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n" |
397 | " .mergeFrom(value).buildPartial();\n" |
398 | " } else {\n" |
399 | " $oneof_name$_ = value;\n" |
400 | " }\n" |
401 | " $set_oneof_case_message$;\n" |
402 | "}\n" ); |
403 | |
404 | // Field.Builder clearField() |
405 | WriteFieldDocComment(printer, field: descriptor_); |
406 | printer->Print(variables: variables_, |
407 | text: "private void clear$capitalized_name$() {\n" |
408 | " if ($has_oneof_case_message$) {\n" |
409 | " $clear_oneof_case_message$;\n" |
410 | " $oneof_name$_ = null;\n" |
411 | " }\n" |
412 | "}\n" ); |
413 | } |
414 | |
415 | void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo( |
416 | io::Printer* printer, std::vector<uint16_t>* output) const { |
417 | WriteIntToUtf16CharSequence(value: descriptor_->number(), output); |
418 | WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_), |
419 | output); |
420 | WriteIntToUtf16CharSequence(value: descriptor_->containing_oneof()->index(), output); |
421 | printer->Print(variables: variables_, text: "$oneof_stored_type$.class,\n" ); |
422 | } |
423 | |
424 | void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers( |
425 | io::Printer* printer) const { |
426 | // The comments above the methods below are based on a hypothetical |
427 | // field of type "Field" called "Field". |
428 | |
429 | // boolean hasField() |
430 | WriteFieldDocComment(printer, field: descriptor_); |
431 | printer->Print(variables: variables_, |
432 | text: "@java.lang.Override\n" |
433 | "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" |
434 | " return instance.has$capitalized_name$();\n" |
435 | "}\n" ); |
436 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
437 | |
438 | // Field getField() |
439 | WriteFieldDocComment(printer, field: descriptor_); |
440 | printer->Print(variables: variables_, |
441 | text: "@java.lang.Override\n" |
442 | "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" |
443 | " return instance.get$capitalized_name$();\n" |
444 | "}\n" ); |
445 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
446 | |
447 | // Field.Builder setField(Field value) |
448 | WriteFieldDocComment(printer, field: descriptor_); |
449 | printer->Print(variables: variables_, |
450 | text: "$deprecation$public Builder " |
451 | "${$set$capitalized_name$$}$($type$ value) {\n" |
452 | " copyOnWrite();\n" |
453 | " instance.set$capitalized_name$(value);\n" |
454 | " return this;\n" |
455 | "}\n" ); |
456 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
457 | |
458 | // Field.Builder setField(Field.Builder builderForValue) |
459 | WriteFieldDocComment(printer, field: descriptor_); |
460 | printer->Print(variables: variables_, |
461 | text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" |
462 | " $type$.Builder builderForValue) {\n" |
463 | " copyOnWrite();\n" |
464 | " instance.set$capitalized_name$(builderForValue.build());\n" |
465 | " return this;\n" |
466 | "}\n" ); |
467 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
468 | |
469 | // Field.Builder mergeField(Field value) |
470 | WriteFieldDocComment(printer, field: descriptor_); |
471 | printer->Print(variables: variables_, |
472 | text: "$deprecation$public Builder " |
473 | "${$merge$capitalized_name$$}$($type$ value) {\n" |
474 | " copyOnWrite();\n" |
475 | " instance.merge$capitalized_name$(value);\n" |
476 | " return this;\n" |
477 | "}\n" ); |
478 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
479 | |
480 | // Field.Builder clearField() |
481 | WriteFieldDocComment(printer, field: descriptor_); |
482 | printer->Print( |
483 | variables: variables_, |
484 | text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" |
485 | " copyOnWrite();\n" |
486 | " instance.clear$capitalized_name$();\n" |
487 | " return this;\n" |
488 | "}\n" ); |
489 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
490 | } |
491 | |
492 | // =================================================================== |
493 | |
494 | RepeatedImmutableMessageFieldLiteGenerator:: |
495 | RepeatedImmutableMessageFieldLiteGenerator( |
496 | const FieldDescriptor* descriptor, int messageBitIndex, |
497 | Context* context) |
498 | : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { |
499 | SetMessageVariables(descriptor, messageBitIndex, builderBitIndex: 0, |
500 | info: context->GetFieldGeneratorInfo(field: descriptor), |
501 | name_resolver: name_resolver_, variables: &variables_); |
502 | } |
503 | |
504 | RepeatedImmutableMessageFieldLiteGenerator:: |
505 | ~RepeatedImmutableMessageFieldLiteGenerator() {} |
506 | |
507 | int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { |
508 | return 0; |
509 | } |
510 | |
511 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers( |
512 | io::Printer* printer) const { |
513 | // TODO(jonp): In the future, consider having methods specific to the |
514 | // interface so that builders can choose dynamically to either return a |
515 | // message or a nested builder, so that asking for the interface doesn't |
516 | // cause a message to ever be built. |
517 | WriteFieldDocComment(printer, field: descriptor_); |
518 | printer->Print(variables: variables_, |
519 | text: "$deprecation$java.util.List<$type$> \n" |
520 | " get$capitalized_name$List();\n" ); |
521 | WriteFieldDocComment(printer, field: descriptor_); |
522 | printer->Print(variables: variables_, |
523 | text: "$deprecation$$type$ get$capitalized_name$(int index);\n" ); |
524 | WriteFieldDocComment(printer, field: descriptor_); |
525 | printer->Print(variables: variables_, |
526 | text: "$deprecation$int get$capitalized_name$Count();\n" ); |
527 | } |
528 | |
529 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers( |
530 | io::Printer* printer) const { |
531 | printer->Print( |
532 | variables: variables_, |
533 | text: "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n" ); |
534 | PrintExtraFieldInfo(variables: variables_, printer); |
535 | WriteFieldDocComment(printer, field: descriptor_); |
536 | printer->Print(variables: variables_, |
537 | text: "@java.lang.Override\n" |
538 | "$deprecation$public java.util.List<$type$> " |
539 | "${$get$capitalized_name$List$}$() {\n" |
540 | " return $name$_;\n" // note: unmodifiable list |
541 | "}\n" ); |
542 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
543 | WriteFieldDocComment(printer, field: descriptor_); |
544 | printer->Print( |
545 | variables: variables_, |
546 | text: "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" |
547 | " ${$get$capitalized_name$OrBuilderList$}$() {\n" |
548 | " return $name$_;\n" |
549 | "}\n" ); |
550 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
551 | WriteFieldDocComment(printer, field: descriptor_); |
552 | printer->Print( |
553 | variables: variables_, |
554 | text: "@java.lang.Override\n" |
555 | "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" |
556 | " return $name$_.size();\n" |
557 | "}\n" ); |
558 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
559 | WriteFieldDocComment(printer, field: descriptor_); |
560 | printer->Print( |
561 | variables: variables_, |
562 | text: "@java.lang.Override\n" |
563 | "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" |
564 | " return $name$_.get(index);\n" |
565 | "}\n" ); |
566 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
567 | WriteFieldDocComment(printer, field: descriptor_); |
568 | printer->Print(variables: variables_, |
569 | text: "$deprecation$public $type$OrBuilder " |
570 | "${$get$capitalized_name$OrBuilder$}$(\n" |
571 | " int index) {\n" |
572 | " return $name$_.get(index);\n" |
573 | "}\n" ); |
574 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
575 | |
576 | printer->Print( |
577 | variables: variables_, |
578 | text: "private void ensure$capitalized_name$IsMutable() {\n" |
579 | // Use a temporary to avoid a redundant iget-object. |
580 | " com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n" |
581 | " if (!tmp.isModifiable()) {\n" |
582 | " $name$_ =\n" |
583 | " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" |
584 | " }\n" |
585 | "}\n" |
586 | "\n" ); |
587 | |
588 | // Builder setRepeatedField(int index, Field value) |
589 | WriteFieldDocComment(printer, field: descriptor_); |
590 | printer->Print(variables: variables_, |
591 | text: "private void set$capitalized_name$(\n" |
592 | " int index, $type$ value) {\n" |
593 | " $null_check$" |
594 | " ensure$capitalized_name$IsMutable();\n" |
595 | " $name$_.set(index, value);\n" |
596 | "}\n" ); |
597 | |
598 | // Builder addRepeatedField(Field value) |
599 | WriteFieldDocComment(printer, field: descriptor_); |
600 | printer->Print(variables: variables_, |
601 | text: "private void add$capitalized_name$($type$ value) {\n" |
602 | " $null_check$" |
603 | " ensure$capitalized_name$IsMutable();\n" |
604 | " $name$_.add(value);\n" |
605 | "}\n" ); |
606 | |
607 | // Builder addRepeatedField(int index, Field value) |
608 | WriteFieldDocComment(printer, field: descriptor_); |
609 | printer->Print(variables: variables_, |
610 | text: "private void add$capitalized_name$(\n" |
611 | " int index, $type$ value) {\n" |
612 | " $null_check$" |
613 | " ensure$capitalized_name$IsMutable();\n" |
614 | " $name$_.add(index, value);\n" |
615 | "}\n" ); |
616 | |
617 | // Builder addAllRepeatedField(Iterable<Field> values) |
618 | WriteFieldDocComment(printer, field: descriptor_); |
619 | printer->Print(variables: variables_, |
620 | text: "private void addAll$capitalized_name$(\n" |
621 | " java.lang.Iterable<? extends $type$> values) {\n" |
622 | " ensure$capitalized_name$IsMutable();\n" |
623 | " com.google.protobuf.AbstractMessageLite.addAll(\n" |
624 | " values, $name$_);\n" |
625 | "}\n" ); |
626 | |
627 | // Builder clearAllRepeatedField() |
628 | WriteFieldDocComment(printer, field: descriptor_); |
629 | printer->Print(variables: variables_, |
630 | text: "private void clear$capitalized_name$() {\n" |
631 | " $name$_ = emptyProtobufList();\n" |
632 | "}\n" ); |
633 | |
634 | // Builder removeRepeatedField(int index) |
635 | WriteFieldDocComment(printer, field: descriptor_); |
636 | printer->Print(variables: variables_, |
637 | text: "private void remove$capitalized_name$(int index) {\n" |
638 | " ensure$capitalized_name$IsMutable();\n" |
639 | " $name$_.remove(index);\n" |
640 | "}\n" ); |
641 | } |
642 | |
643 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers( |
644 | io::Printer* printer) const { |
645 | // The comments above the methods below are based on a hypothetical |
646 | // repeated field of type "Field" called "RepeatedField". |
647 | |
648 | // List<Field> getRepeatedFieldList() |
649 | WriteFieldDocComment(printer, field: descriptor_); |
650 | printer->Print(variables: variables_, |
651 | text: "@java.lang.Override\n" |
652 | "$deprecation$public java.util.List<$type$> " |
653 | "${$get$capitalized_name$List$}$() {\n" |
654 | " return java.util.Collections.unmodifiableList(\n" |
655 | " instance.get$capitalized_name$List());\n" |
656 | "}\n" ); |
657 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
658 | |
659 | // int getRepeatedFieldCount() |
660 | WriteFieldDocComment(printer, field: descriptor_); |
661 | printer->Print( |
662 | variables: variables_, |
663 | text: "@java.lang.Override\n" |
664 | "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" |
665 | " return instance.get$capitalized_name$Count();\n" |
666 | "}" ); |
667 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
668 | |
669 | // Field getRepeatedField(int index) |
670 | WriteFieldDocComment(printer, field: descriptor_); |
671 | printer->Print( |
672 | variables: variables_, |
673 | text: "@java.lang.Override\n" |
674 | "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" |
675 | " return instance.get$capitalized_name$(index);\n" |
676 | "}\n" ); |
677 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
678 | |
679 | // Builder setRepeatedField(int index, Field value) |
680 | WriteFieldDocComment(printer, field: descriptor_); |
681 | printer->Print(variables: variables_, |
682 | text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" |
683 | " int index, $type$ value) {\n" |
684 | " copyOnWrite();\n" |
685 | " instance.set$capitalized_name$(index, value);\n" |
686 | " return this;\n" |
687 | "}\n" ); |
688 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
689 | |
690 | // Builder setRepeatedField(int index, Field.Builder builderForValue) |
691 | WriteFieldDocComment(printer, field: descriptor_); |
692 | printer->Print(variables: variables_, |
693 | text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" |
694 | " int index, $type$.Builder builderForValue) {\n" |
695 | " copyOnWrite();\n" |
696 | " instance.set$capitalized_name$(index,\n" |
697 | " builderForValue.build());\n" |
698 | " return this;\n" |
699 | "}\n" ); |
700 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
701 | |
702 | // Builder addRepeatedField(Field value) |
703 | WriteFieldDocComment(printer, field: descriptor_); |
704 | printer->Print(variables: variables_, |
705 | text: "$deprecation$public Builder " |
706 | "${$add$capitalized_name$$}$($type$ value) {\n" |
707 | " copyOnWrite();\n" |
708 | " instance.add$capitalized_name$(value);\n" |
709 | " return this;\n" |
710 | "}\n" ); |
711 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
712 | |
713 | // Builder addRepeatedField(int index, Field value) |
714 | WriteFieldDocComment(printer, field: descriptor_); |
715 | printer->Print(variables: variables_, |
716 | text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" |
717 | " int index, $type$ value) {\n" |
718 | " copyOnWrite();\n" |
719 | " instance.add$capitalized_name$(index, value);\n" |
720 | " return this;\n" |
721 | "}\n" ); |
722 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
723 | // Builder addRepeatedField(Field.Builder builderForValue) |
724 | WriteFieldDocComment(printer, field: descriptor_); |
725 | printer->Print(variables: variables_, |
726 | text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" |
727 | " $type$.Builder builderForValue) {\n" |
728 | " copyOnWrite();\n" |
729 | " instance.add$capitalized_name$(builderForValue.build());\n" |
730 | " return this;\n" |
731 | "}\n" ); |
732 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
733 | |
734 | // Builder addRepeatedField(int index, Field.Builder builderForValue) |
735 | WriteFieldDocComment(printer, field: descriptor_); |
736 | printer->Print(variables: variables_, |
737 | text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" |
738 | " int index, $type$.Builder builderForValue) {\n" |
739 | " copyOnWrite();\n" |
740 | " instance.add$capitalized_name$(index,\n" |
741 | " builderForValue.build());\n" |
742 | " return this;\n" |
743 | "}\n" ); |
744 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
745 | |
746 | // Builder addAllRepeatedField(Iterable<Field> values) |
747 | WriteFieldDocComment(printer, field: descriptor_); |
748 | printer->Print(variables: variables_, |
749 | text: "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" |
750 | " java.lang.Iterable<? extends $type$> values) {\n" |
751 | " copyOnWrite();\n" |
752 | " instance.addAll$capitalized_name$(values);\n" |
753 | " return this;\n" |
754 | "}\n" ); |
755 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
756 | |
757 | // Builder clearAllRepeatedField() |
758 | WriteFieldDocComment(printer, field: descriptor_); |
759 | printer->Print( |
760 | variables: variables_, |
761 | text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" |
762 | " copyOnWrite();\n" |
763 | " instance.clear$capitalized_name$();\n" |
764 | " return this;\n" |
765 | "}\n" ); |
766 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
767 | |
768 | // Builder removeRepeatedField(int index) |
769 | WriteFieldDocComment(printer, field: descriptor_); |
770 | printer->Print(variables: variables_, |
771 | text: "$deprecation$public Builder " |
772 | "${$remove$capitalized_name$$}$(int index) {\n" |
773 | " copyOnWrite();\n" |
774 | " instance.remove$capitalized_name$(index);\n" |
775 | " return this;\n" |
776 | "}\n" ); |
777 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
778 | } |
779 | |
780 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo( |
781 | io::Printer* printer, std::vector<uint16_t>* output) const { |
782 | WriteIntToUtf16CharSequence(value: descriptor_->number(), output); |
783 | WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_), |
784 | output); |
785 | printer->Print(variables: variables_, |
786 | text: "\"$name$_\",\n" |
787 | "$type$.class,\n" ); |
788 | } |
789 | |
790 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode( |
791 | io::Printer* printer) const { |
792 | printer->Print(variables: variables_, text: "$name$_ = emptyProtobufList();\n" ); |
793 | } |
794 | |
795 | std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const { |
796 | return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type()); |
797 | } |
798 | |
799 | void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( |
800 | io::Printer* printer) const { |
801 | printer->Print( |
802 | variables: variables_, |
803 | text: "/**\n" |
804 | " * An uninstantiable, behaviorless type to represent the field in\n" |
805 | " * generics.\n" |
806 | " */\n" |
807 | "@kotlin.OptIn" |
808 | "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" |
809 | "class ${$$kt_capitalized_name$Proxy$}$ private constructor()" |
810 | " : com.google.protobuf.kotlin.DslProxy()\n" ); |
811 | |
812 | WriteFieldDocComment(printer, field: descriptor_); |
813 | printer->Print(variables: variables_, |
814 | text: "$kt_deprecation$ val $kt_name$: " |
815 | "com.google.protobuf.kotlin.DslList" |
816 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
817 | " @kotlin.jvm.JvmSynthetic\n" |
818 | " get() = com.google.protobuf.kotlin.DslList(\n" |
819 | " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" |
820 | " )\n" ); |
821 | |
822 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER, |
823 | /* builder */ false); |
824 | printer->Print(variables: variables_, |
825 | text: "@kotlin.jvm.JvmSynthetic\n" |
826 | "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" |
827 | "fun com.google.protobuf.kotlin.DslList" |
828 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
829 | "add(value: $kt_type$) {\n" |
830 | " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" |
831 | "}\n" ); |
832 | |
833 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER, |
834 | /* builder */ false); |
835 | printer->Print(variables: variables_, |
836 | text: "@kotlin.jvm.JvmSynthetic\n" |
837 | "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" |
838 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
839 | "inline operator fun com.google.protobuf.kotlin.DslList" |
840 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
841 | "plusAssign(value: $kt_type$) {\n" |
842 | " add(value)\n" |
843 | "}\n" ); |
844 | |
845 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER, |
846 | /* builder */ false); |
847 | printer->Print(variables: variables_, |
848 | text: "@kotlin.jvm.JvmSynthetic\n" |
849 | "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" |
850 | "fun com.google.protobuf.kotlin.DslList" |
851 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
852 | "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" |
853 | " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" |
854 | "}\n" ); |
855 | |
856 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER, |
857 | /* builder */ false); |
858 | printer->Print( |
859 | variables: variables_, |
860 | text: "@kotlin.jvm.JvmSynthetic\n" |
861 | "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" |
862 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
863 | "inline operator fun com.google.protobuf.kotlin.DslList" |
864 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
865 | "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" |
866 | " addAll(values)\n" |
867 | "}\n" ); |
868 | |
869 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_SETTER, |
870 | /* builder */ false); |
871 | printer->Print( |
872 | variables: variables_, |
873 | text: "@kotlin.jvm.JvmSynthetic\n" |
874 | "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" |
875 | "operator fun com.google.protobuf.kotlin.DslList" |
876 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
877 | "set(index: kotlin.Int, value: $kt_type$) {\n" |
878 | " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" |
879 | "}\n" ); |
880 | |
881 | WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, |
882 | /* builder */ false); |
883 | printer->Print(variables: variables_, |
884 | text: "@kotlin.jvm.JvmSynthetic\n" |
885 | "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" |
886 | "fun com.google.protobuf.kotlin.DslList" |
887 | "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." |
888 | "clear() {\n" |
889 | " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" |
890 | "}\n" ); |
891 | } |
892 | |
893 | } // namespace java |
894 | } // namespace compiler |
895 | } // namespace protobuf |
896 | } // namespace google |
897 | |
898 | #include <google/protobuf/port_undef.inc> |
899 | |