~verterok/ubuntu/lucid/protobuf/2.4.0a-backport

« back to all changes in this revision

Viewing changes to src/google/protobuf/compiler/java/java_primitive_field.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-05-31 14:41:47 UTC
  • mfrom: (2.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110531144147-s41g5fozgvyo462l
Tags: 2.4.0a-2ubuntu1
* Merge with Debian; remaining changes:
  - Fix linking with -lpthread.

Show diffs side-by-side

added added

removed removed

Lines of Context:
154
154
}
155
155
 
156
156
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
 
157
                           int messageBitIndex,
 
158
                           int builderBitIndex,
157
159
                           map<string, string>* variables) {
158
160
  (*variables)["name"] =
159
161
    UnderscoresToCamelCase(descriptor);
160
162
  (*variables)["capitalized_name"] =
161
163
    UnderscoresToCapitalizedCamelCase(descriptor);
 
164
  (*variables)["constant_name"] = FieldConstantName(descriptor);
162
165
  (*variables)["number"] = SimpleItoa(descriptor->number());
163
166
  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
164
167
  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
 
168
  (*variables)["field_type"] = (*variables)["type"];
 
169
  (*variables)["field_list_type"] = "java.util.List<" +
 
170
      (*variables)["boxed_type"] + ">";
 
171
  (*variables)["empty_list"] = "java.util.Collections.emptyList();";
165
172
  (*variables)["default"] = DefaultValue(descriptor);
 
173
  (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
 
174
      "" : ("= " + DefaultValue(descriptor));
166
175
  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
167
176
  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
168
177
  (*variables)["tag_size"] = SimpleItoa(
175
184
  } else {
176
185
    (*variables)["null_check"] = "";
177
186
  }
 
187
  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
 
188
  // by the proto compiler
 
189
  (*variables)["deprecation"] = descriptor->options().deprecated()
 
190
      ? "@java.lang.Deprecated " : "";
178
191
  int fixed_size = FixedSize(GetType(descriptor));
179
192
  if (fixed_size != -1) {
180
193
    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
181
194
  }
 
195
  (*variables)["on_changed"] =
 
196
      HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
 
197
 
 
198
  // For singular messages and builders, one bit is used for the hasField bit.
 
199
  (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
 
200
 
 
201
  (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
 
202
  (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
 
203
  (*variables)["clear_has_field_bit_builder"] =
 
204
      GenerateClearBit(builderBitIndex);
 
205
 
 
206
  // For repated builders, one bit is used for whether the array is immutable.
 
207
  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
 
208
  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
 
209
  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
 
210
 
 
211
  (*variables)["get_has_field_bit_from_local"] =
 
212
      GenerateGetBitFromLocal(builderBitIndex);
 
213
  (*variables)["set_has_field_bit_to_local"] =
 
214
      GenerateSetBitToLocal(messageBitIndex);
182
215
}
 
216
 
183
217
}  // namespace
184
218
 
185
219
// ===================================================================
186
220
 
187
221
PrimitiveFieldGenerator::
188
 
PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
189
 
  : descriptor_(descriptor) {
190
 
  SetPrimitiveVariables(descriptor, &variables_);
 
222
PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
 
223
                        int messageBitIndex,
 
224
                        int builderBitIndex)
 
225
  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
 
226
    builderBitIndex_(builderBitIndex) {
 
227
  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
 
228
                        &variables_);
191
229
}
192
230
 
193
231
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
194
232
 
 
233
int PrimitiveFieldGenerator::GetNumBitsForMessage() const {
 
234
  return 1;
 
235
}
 
236
 
 
237
int PrimitiveFieldGenerator::GetNumBitsForBuilder() const {
 
238
  return 1;
 
239
}
 
240
 
 
241
void PrimitiveFieldGenerator::
 
242
GenerateInterfaceMembers(io::Printer* printer) const {
 
243
  printer->Print(variables_,
 
244
    "$deprecation$boolean has$capitalized_name$();\n"
 
245
    "$deprecation$$type$ get$capitalized_name$();\n");
 
246
}
 
247
 
195
248
void PrimitiveFieldGenerator::
196
249
GenerateMembers(io::Printer* printer) const {
197
250
  printer->Print(variables_,
198
 
    "private boolean has$capitalized_name$;\n"
199
 
    "private $type$ $name$_ = $default$;\n"
200
 
    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
201
 
    "public $type$ get$capitalized_name$() { return $name$_; }\n");
 
251
    "private $field_type$ $name$_;\n"
 
252
    "$deprecation$public boolean has$capitalized_name$() {\n"
 
253
    "  return $get_has_field_bit_message$;\n"
 
254
    "}\n");
 
255
 
 
256
  printer->Print(variables_,
 
257
    "$deprecation$public $type$ get$capitalized_name$() {\n"
 
258
    "  return $name$_;\n"
 
259
    "}\n");
202
260
}
203
261
 
204
262
void PrimitiveFieldGenerator::
205
263
GenerateBuilderMembers(io::Printer* printer) const {
206
264
  printer->Print(variables_,
207
 
    "public boolean has$capitalized_name$() {\n"
208
 
    "  return result.has$capitalized_name$();\n"
209
 
    "}\n"
210
 
    "public $type$ get$capitalized_name$() {\n"
211
 
    "  return result.get$capitalized_name$();\n"
212
 
    "}\n"
213
 
    "public Builder set$capitalized_name$($type$ value) {\n"
 
265
    "private $field_type$ $name$_ $default_init$;\n"
 
266
    "$deprecation$public boolean has$capitalized_name$() {\n"
 
267
    "  return $get_has_field_bit_builder$;\n"
 
268
    "}\n");
 
269
 
 
270
  printer->Print(variables_,
 
271
    "$deprecation$public $type$ get$capitalized_name$() {\n"
 
272
    "  return $name$_;\n"
 
273
    "}\n");
 
274
 
 
275
  printer->Print(variables_,
 
276
    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
214
277
    "$null_check$"
215
 
    "  result.has$capitalized_name$ = true;\n"
216
 
    "  result.$name$_ = value;\n"
 
278
    "  $set_has_field_bit_builder$;\n"
 
279
    "  $name$_ = value;\n"
 
280
    "  $on_changed$\n"
217
281
    "  return this;\n"
218
282
    "}\n"
219
 
    "public Builder clear$capitalized_name$() {\n"
220
 
    "  result.has$capitalized_name$ = false;\n");
 
283
    "$deprecation$public Builder clear$capitalized_name$() {\n"
 
284
    "  $clear_has_field_bit_builder$;\n");
221
285
  JavaType type = GetJavaType(descriptor_);
222
286
  if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
223
287
    // The default value is not a simple literal so we want to avoid executing
224
288
    // it multiple times.  Instead, get the default out of the default instance.
225
289
    printer->Print(variables_,
226
 
      "  result.$name$_ = getDefaultInstance().get$capitalized_name$();\n");
 
290
      "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
227
291
  } else {
228
292
    printer->Print(variables_,
229
 
      "  result.$name$_ = $default$;\n");
 
293
      "  $name$_ = $default$;\n");
230
294
  }
231
295
  printer->Print(variables_,
 
296
    "  $on_changed$\n"
232
297
    "  return this;\n"
233
298
    "}\n");
234
299
}
235
300
 
236
301
void PrimitiveFieldGenerator::
 
302
GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
 
303
  // noop for primitives
 
304
}
 
305
 
 
306
void PrimitiveFieldGenerator::
237
307
GenerateInitializationCode(io::Printer* printer) const {
238
 
  // Initialized inline.
 
308
  printer->Print(variables_, "$name$_ = $default$;\n");
 
309
}
 
310
 
 
311
void PrimitiveFieldGenerator::
 
312
GenerateBuilderClearCode(io::Printer* printer) const {
 
313
  printer->Print(variables_,
 
314
    "$name$_ = $default$;\n"
 
315
    "$clear_has_field_bit_builder$;\n");
239
316
}
240
317
 
241
318
void PrimitiveFieldGenerator::
248
325
 
249
326
void PrimitiveFieldGenerator::
250
327
GenerateBuildingCode(io::Printer* printer) const {
251
 
  // Nothing to do here for primitive types.
 
328
  printer->Print(variables_,
 
329
    "if ($get_has_field_bit_from_local$) {\n"
 
330
    "  $set_has_field_bit_to_local$;\n"
 
331
    "}\n"
 
332
    "result.$name$_ = $name$_;\n");
252
333
}
253
334
 
254
335
void PrimitiveFieldGenerator::
255
336
GenerateParsingCode(io::Printer* printer) const {
256
337
  printer->Print(variables_,
257
 
    "set$capitalized_name$(input.read$capitalized_type$());\n");
 
338
    "$set_has_field_bit_builder$;\n"
 
339
    "$name$_ = input.read$capitalized_type$();\n");
258
340
}
259
341
 
260
342
void PrimitiveFieldGenerator::
261
343
GenerateSerializationCode(io::Printer* printer) const {
262
344
  printer->Print(variables_,
263
 
    "if (has$capitalized_name$()) {\n"
264
 
    "  output.write$capitalized_type$($number$, get$capitalized_name$());\n"
 
345
    "if ($get_has_field_bit_message$) {\n"
 
346
    "  output.write$capitalized_type$($number$, $name$_);\n"
265
347
    "}\n");
266
348
}
267
349
 
268
350
void PrimitiveFieldGenerator::
269
351
GenerateSerializedSizeCode(io::Printer* printer) const {
270
352
  printer->Print(variables_,
271
 
    "if (has$capitalized_name$()) {\n"
 
353
    "if ($get_has_field_bit_message$) {\n"
272
354
    "  size += com.google.protobuf.CodedOutputStream\n"
273
 
    "    .compute$capitalized_type$Size($number$, get$capitalized_name$());\n"
 
355
    "    .compute$capitalized_type$Size($number$, $name$_);\n"
274
356
    "}\n");
275
357
}
276
358
 
 
359
void PrimitiveFieldGenerator::
 
360
GenerateEqualsCode(io::Printer* printer) const {
 
361
  switch (GetJavaType(descriptor_)) {
 
362
    case JAVATYPE_INT:
 
363
    case JAVATYPE_LONG:
 
364
    case JAVATYPE_BOOLEAN:
 
365
      printer->Print(variables_,
 
366
        "result = result && (get$capitalized_name$()\n"
 
367
        "    == other.get$capitalized_name$());\n");
 
368
      break;
 
369
 
 
370
    case JAVATYPE_FLOAT:
 
371
      printer->Print(variables_,
 
372
        "result = result && (Float.floatToIntBits(get$capitalized_name$())"
 
373
        "    == Float.floatToIntBits(other.get$capitalized_name$()));\n");
 
374
      break;
 
375
 
 
376
    case JAVATYPE_DOUBLE:
 
377
      printer->Print(variables_,
 
378
        "result = result && (Double.doubleToLongBits(get$capitalized_name$())"
 
379
        "    == Double.doubleToLongBits(other.get$capitalized_name$()));\n");
 
380
      break;
 
381
 
 
382
    case JAVATYPE_STRING:
 
383
    case JAVATYPE_BYTES:
 
384
      printer->Print(variables_,
 
385
        "result = result && get$capitalized_name$()\n"
 
386
        "    .equals(other.get$capitalized_name$());\n");
 
387
      break;
 
388
 
 
389
    case JAVATYPE_ENUM:
 
390
    case JAVATYPE_MESSAGE:
 
391
    default:
 
392
      GOOGLE_LOG(FATAL) << "Can't get here.";
 
393
      break;
 
394
  }
 
395
}
 
396
 
 
397
void PrimitiveFieldGenerator::
 
398
GenerateHashCode(io::Printer* printer) const {
 
399
  printer->Print(variables_,
 
400
    "hash = (37 * hash) + $constant_name$;\n");
 
401
  switch (GetJavaType(descriptor_)) {
 
402
    case JAVATYPE_INT:
 
403
      printer->Print(variables_,
 
404
        "hash = (53 * hash) + get$capitalized_name$();\n");
 
405
      break;
 
406
 
 
407
    case JAVATYPE_LONG:
 
408
      printer->Print(variables_,
 
409
        "hash = (53 * hash) + hashLong(get$capitalized_name$());\n");
 
410
      break;
 
411
 
 
412
    case JAVATYPE_BOOLEAN:
 
413
      printer->Print(variables_,
 
414
        "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n");
 
415
      break;
 
416
 
 
417
    case JAVATYPE_FLOAT:
 
418
      printer->Print(variables_,
 
419
        "hash = (53 * hash) + Float.floatToIntBits(\n"
 
420
        "    get$capitalized_name$());\n");
 
421
      break;
 
422
 
 
423
    case JAVATYPE_DOUBLE:
 
424
      printer->Print(variables_,
 
425
        "hash = (53 * hash) + hashLong(\n"
 
426
        "    Double.doubleToLongBits(get$capitalized_name$()));\n");
 
427
      break;
 
428
 
 
429
    case JAVATYPE_STRING:
 
430
    case JAVATYPE_BYTES:
 
431
      printer->Print(variables_,
 
432
        "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
 
433
      break;
 
434
 
 
435
    case JAVATYPE_ENUM:
 
436
    case JAVATYPE_MESSAGE:
 
437
    default:
 
438
      GOOGLE_LOG(FATAL) << "Can't get here.";
 
439
      break;
 
440
  }
 
441
}
 
442
 
277
443
string PrimitiveFieldGenerator::GetBoxedType() const {
278
444
  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
279
445
}
281
447
// ===================================================================
282
448
 
283
449
RepeatedPrimitiveFieldGenerator::
284
 
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
285
 
  : descriptor_(descriptor) {
286
 
  SetPrimitiveVariables(descriptor, &variables_);
 
450
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
 
451
                                int messageBitIndex,
 
452
                                int builderBitIndex)
 
453
  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
 
454
    builderBitIndex_(builderBitIndex) {
 
455
  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
 
456
                        &variables_);
287
457
}
288
458
 
289
459
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
290
460
 
 
461
int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const {
 
462
  return 0;
 
463
}
 
464
 
 
465
int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const {
 
466
  return 1;
 
467
}
 
468
 
 
469
void RepeatedPrimitiveFieldGenerator::
 
470
GenerateInterfaceMembers(io::Printer* printer) const {
 
471
  printer->Print(variables_,
 
472
    "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"
 
473
    "$deprecation$int get$capitalized_name$Count();\n"
 
474
    "$deprecation$$type$ get$capitalized_name$(int index);\n");
 
475
}
 
476
 
 
477
 
291
478
void RepeatedPrimitiveFieldGenerator::
292
479
GenerateMembers(io::Printer* printer) const {
293
480
  printer->Print(variables_,
294
 
    "private java.util.List<$boxed_type$> $name$_ =\n"
295
 
    "  java.util.Collections.emptyList();\n"
296
 
    "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
 
481
    "private $field_list_type$ $name$_;\n"
 
482
    "$deprecation$public java.util.List<$boxed_type$>\n"
 
483
    "    get$capitalized_name$List() {\n"
297
484
    "  return $name$_;\n"   // note:  unmodifiable list
298
485
    "}\n"
299
 
    "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
300
 
    "public $type$ get$capitalized_name$(int index) {\n"
 
486
    "$deprecation$public int get$capitalized_name$Count() {\n"
 
487
    "  return $name$_.size();\n"
 
488
    "}\n"
 
489
    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
301
490
    "  return $name$_.get(index);\n"
302
491
    "}\n");
303
492
 
310
499
 
311
500
void RepeatedPrimitiveFieldGenerator::
312
501
GenerateBuilderMembers(io::Printer* printer) const {
313
 
  printer->Print(variables_,
 
502
  // One field is the list and the bit field keeps track of whether the
 
503
  // list is immutable. If it's immutable, the invariant is that it must
 
504
  // either an instance of Collections.emptyList() or it's an ArrayList
 
505
  // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
 
506
  // a refererence to the underlying ArrayList. This invariant allows us to
 
507
  // share instances of lists between protocol buffers avoiding expensive
 
508
  // memory allocations. Note, immutable is a strong guarantee here -- not
 
509
  // just that the list cannot be modified via the reference but that the
 
510
  // list can never be modified.
 
511
  printer->Print(variables_,
 
512
    "private $field_list_type$ $name$_ = $empty_list$;\n");
 
513
 
 
514
  printer->Print(variables_,
 
515
    "private void ensure$capitalized_name$IsMutable() {\n"
 
516
    "  if (!$get_mutable_bit_builder$) {\n"
 
517
    "    $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
 
518
    "    $set_mutable_bit_builder$;\n"
 
519
    "   }\n"
 
520
    "}\n");
 
521
 
314
522
    // Note:  We return an unmodifiable list because otherwise the caller
315
523
    //   could hold on to the returned list and modify it after the message
316
524
    //   has been built, thus mutating the message which is supposed to be
317
525
    //   immutable.
318
 
    "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
319
 
    "  return java.util.Collections.unmodifiableList(result.$name$_);\n"
320
 
    "}\n"
321
 
    "public int get$capitalized_name$Count() {\n"
322
 
    "  return result.get$capitalized_name$Count();\n"
323
 
    "}\n"
324
 
    "public $type$ get$capitalized_name$(int index) {\n"
325
 
    "  return result.get$capitalized_name$(index);\n"
326
 
    "}\n"
327
 
    "public Builder set$capitalized_name$(int index, $type$ value) {\n"
328
 
    "$null_check$"
329
 
    "  result.$name$_.set(index, value);\n"
330
 
    "  return this;\n"
331
 
    "}\n"
332
 
    "public Builder add$capitalized_name$($type$ value) {\n"
333
 
    "$null_check$"
334
 
    "  if (result.$name$_.isEmpty()) {\n"
335
 
    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
336
 
    "  }\n"
337
 
    "  result.$name$_.add(value);\n"
338
 
    "  return this;\n"
339
 
    "}\n"
340
 
    "public Builder addAll$capitalized_name$(\n"
 
526
  printer->Print(variables_,
 
527
    "$deprecation$public java.util.List<$boxed_type$>\n"
 
528
    "    get$capitalized_name$List() {\n"
 
529
    "  return java.util.Collections.unmodifiableList($name$_);\n"
 
530
    "}\n"
 
531
    "$deprecation$public int get$capitalized_name$Count() {\n"
 
532
    "  return $name$_.size();\n"
 
533
    "}\n"
 
534
    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
 
535
    "  return $name$_.get(index);\n"
 
536
    "}\n"
 
537
    "$deprecation$public Builder set$capitalized_name$(\n"
 
538
    "    int index, $type$ value) {\n"
 
539
    "$null_check$"
 
540
    "  ensure$capitalized_name$IsMutable();\n"
 
541
    "  $name$_.set(index, value);\n"
 
542
    "  $on_changed$\n"
 
543
    "  return this;\n"
 
544
    "}\n"
 
545
    "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
 
546
    "$null_check$"
 
547
    "  ensure$capitalized_name$IsMutable();\n"
 
548
    "  $name$_.add(value);\n"
 
549
    "  $on_changed$\n"
 
550
    "  return this;\n"
 
551
    "}\n"
 
552
    "$deprecation$public Builder addAll$capitalized_name$(\n"
341
553
    "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
342
 
    "  if (result.$name$_.isEmpty()) {\n"
343
 
    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
344
 
    "  }\n"
345
 
    "  super.addAll(values, result.$name$_);\n"
 
554
    "  ensure$capitalized_name$IsMutable();\n"
 
555
    "  super.addAll(values, $name$_);\n"
 
556
    "  $on_changed$\n"
346
557
    "  return this;\n"
347
558
    "}\n"
348
 
    "public Builder clear$capitalized_name$() {\n"
349
 
    "  result.$name$_ = java.util.Collections.emptyList();\n"
 
559
    "$deprecation$public Builder clear$capitalized_name$() {\n"
 
560
    "  $name$_ = $empty_list$;\n"
 
561
    "  $clear_mutable_bit_builder$;\n"
 
562
    "  $on_changed$\n"
350
563
    "  return this;\n"
351
564
    "}\n");
352
565
}
353
566
 
354
567
void RepeatedPrimitiveFieldGenerator::
 
568
GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
 
569
  // noop for primitives
 
570
}
 
571
 
 
572
void RepeatedPrimitiveFieldGenerator::
355
573
GenerateInitializationCode(io::Printer* printer) const {
356
 
  // Initialized inline.
 
574
  printer->Print(variables_, "$name$_ = $empty_list$;\n");
 
575
}
 
576
 
 
577
void RepeatedPrimitiveFieldGenerator::
 
578
GenerateBuilderClearCode(io::Printer* printer) const {
 
579
  printer->Print(variables_,
 
580
    "$name$_ = $empty_list$;\n"
 
581
    "$clear_mutable_bit_builder$;\n");
357
582
}
358
583
 
359
584
void RepeatedPrimitiveFieldGenerator::
360
585
GenerateMergingCode(io::Printer* printer) const {
 
586
  // The code below does two optimizations:
 
587
  //   1. If the other list is empty, there's nothing to do. This ensures we
 
588
  //      don't allocate a new array if we already have an immutable one.
 
589
  //   2. If the other list is non-empty and our current list is empty, we can
 
590
  //      reuse the other list which is guaranteed to be immutable.
361
591
  printer->Print(variables_,
362
592
    "if (!other.$name$_.isEmpty()) {\n"
363
 
    "  if (result.$name$_.isEmpty()) {\n"
364
 
    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
 
593
    "  if ($name$_.isEmpty()) {\n"
 
594
    "    $name$_ = other.$name$_;\n"
 
595
    "    $clear_mutable_bit_builder$;\n"
 
596
    "  } else {\n"
 
597
    "    ensure$capitalized_name$IsMutable();\n"
 
598
    "    $name$_.addAll(other.$name$_);\n"
365
599
    "  }\n"
366
 
    "  result.$name$_.addAll(other.$name$_);\n"
 
600
    "  $on_changed$\n"
367
601
    "}\n");
368
602
}
369
603
 
370
604
void RepeatedPrimitiveFieldGenerator::
371
605
GenerateBuildingCode(io::Printer* printer) const {
 
606
  // The code below ensures that the result has an immutable list. If our
 
607
  // list is immutable, we can just reuse it. If not, we make it immutable.
372
608
  printer->Print(variables_,
373
 
    "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
374
 
    "  result.$name$_ =\n"
375
 
    "    java.util.Collections.unmodifiableList(result.$name$_);\n"
376
 
    "}\n");
 
609
    "if ($get_mutable_bit_builder$) {\n"
 
610
    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
 
611
    "  $clear_mutable_bit_builder$;\n"
 
612
    "}\n"
 
613
    "result.$name$_ = $name$_;\n");
377
614
}
378
615
 
379
616
void RepeatedPrimitiveFieldGenerator::
380
617
GenerateParsingCode(io::Printer* printer) const {
381
618
  printer->Print(variables_,
382
 
    "add$capitalized_name$(input.read$capitalized_type$());\n");
 
619
    "ensure$capitalized_name$IsMutable();\n"
 
620
    "$name$_.add(input.read$capitalized_type$());\n");
383
621
}
384
622
 
385
623
void RepeatedPrimitiveFieldGenerator::
401
639
      "  output.writeRawVarint32($tag$);\n"
402
640
      "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
403
641
      "}\n"
404
 
      "for ($type$ element : get$capitalized_name$List()) {\n"
405
 
      "  output.write$capitalized_type$NoTag(element);\n"
 
642
      "for (int i = 0; i < $name$_.size(); i++) {\n"
 
643
      "  output.write$capitalized_type$NoTag($name$_.get(i));\n"
406
644
      "}\n");
407
645
  } else {
408
646
    printer->Print(variables_,
409
 
      "for ($type$ element : get$capitalized_name$List()) {\n"
410
 
      "  output.write$capitalized_type$($number$, element);\n"
 
647
      "for (int i = 0; i < $name$_.size(); i++) {\n"
 
648
      "  output.write$capitalized_type$($number$, $name$_.get(i));\n"
411
649
      "}\n");
412
650
  }
413
651
}
421
659
 
422
660
  if (FixedSize(GetType(descriptor_)) == -1) {
423
661
    printer->Print(variables_,
424
 
      "for ($type$ element : get$capitalized_name$List()) {\n"
 
662
      "for (int i = 0; i < $name$_.size(); i++) {\n"
425
663
      "  dataSize += com.google.protobuf.CodedOutputStream\n"
426
 
      "    .compute$capitalized_type$SizeNoTag(element);\n"
 
664
      "    .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
427
665
      "}\n");
428
666
  } else {
429
667
    printer->Print(variables_,
455
693
  printer->Print("}\n");
456
694
}
457
695
 
 
696
void RepeatedPrimitiveFieldGenerator::
 
697
GenerateEqualsCode(io::Printer* printer) const {
 
698
  printer->Print(variables_,
 
699
    "result = result && get$capitalized_name$List()\n"
 
700
    "    .equals(other.get$capitalized_name$List());\n");
 
701
}
 
702
 
 
703
void RepeatedPrimitiveFieldGenerator::
 
704
GenerateHashCode(io::Printer* printer) const {
 
705
  printer->Print(variables_,
 
706
    "if (get$capitalized_name$Count() > 0) {\n"
 
707
    "  hash = (37 * hash) + $constant_name$;\n"
 
708
    "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
 
709
    "}\n");
 
710
}
 
711
 
458
712
string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
459
713
  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
460
714
}