~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to protobuf/files/src/google/protobuf/compiler/cpp/cpp_message.cc

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.  All rights reserved.
3
 
// http://code.google.com/p/protobuf/
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 <algorithm>
36
 
#include <google/protobuf/stubs/hash.h>
37
 
#include <map>
38
 
#include <vector>
39
 
#include <google/protobuf/compiler/cpp/cpp_message.h>
40
 
#include <google/protobuf/compiler/cpp/cpp_field.h>
41
 
#include <google/protobuf/compiler/cpp/cpp_enum.h>
42
 
#include <google/protobuf/compiler/cpp/cpp_extension.h>
43
 
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
44
 
#include <google/protobuf/stubs/strutil.h>
45
 
#include <google/protobuf/io/printer.h>
46
 
#include <google/protobuf/io/coded_stream.h>
47
 
#include <google/protobuf/wire_format.h>
48
 
#include <google/protobuf/descriptor.pb.h>
49
 
 
50
 
namespace google {
51
 
namespace protobuf {
52
 
namespace compiler {
53
 
namespace cpp {
54
 
 
55
 
using internal::WireFormat;
56
 
using internal::WireFormatLite;
57
 
 
58
 
namespace {
59
 
 
60
 
void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
61
 
  // Print the field's proto-syntax definition as a comment.  We don't want to
62
 
  // print group bodies so we cut off after the first line.
63
 
  string def = field->DebugString();
64
 
  printer->Print("// $def$\n",
65
 
    "def", def.substr(0, def.find_first_of('\n')));
66
 
}
67
 
 
68
 
struct FieldOrderingByNumber {
69
 
  inline bool operator()(const FieldDescriptor* a,
70
 
                         const FieldDescriptor* b) const {
71
 
    return a->number() < b->number();
72
 
  }
73
 
};
74
 
 
75
 
const char* kWireTypeNames[] = {
76
 
  "VARINT",
77
 
  "FIXED64",
78
 
  "LENGTH_DELIMITED",
79
 
  "START_GROUP",
80
 
  "END_GROUP",
81
 
  "FIXED32",
82
 
};
83
 
 
84
 
// Sort the fields of the given Descriptor by number into a new[]'d array
85
 
// and return it.
86
 
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
87
 
  const FieldDescriptor** fields =
88
 
    new const FieldDescriptor*[descriptor->field_count()];
89
 
  for (int i = 0; i < descriptor->field_count(); i++) {
90
 
    fields[i] = descriptor->field(i);
91
 
  }
92
 
  sort(fields, fields + descriptor->field_count(),
93
 
       FieldOrderingByNumber());
94
 
  return fields;
95
 
}
96
 
 
97
 
// Functor for sorting extension ranges by their "start" field number.
98
 
struct ExtensionRangeSorter {
99
 
  bool operator()(const Descriptor::ExtensionRange* left,
100
 
                  const Descriptor::ExtensionRange* right) const {
101
 
    return left->start < right->start;
102
 
  }
103
 
};
104
 
 
105
 
// Returns true if the message type has any required fields.  If it doesn't,
106
 
// we can optimize out calls to its IsInitialized() method.
107
 
//
108
 
// already_seen is used to avoid checking the same type multiple times
109
 
// (and also to protect against recursion).
110
 
static bool HasRequiredFields(
111
 
    const Descriptor* type,
112
 
    hash_set<const Descriptor*>* already_seen) {
113
 
  if (already_seen->count(type) > 0) {
114
 
    // Since the first occurrence of a required field causes the whole
115
 
    // function to return true, we can assume that if the type is already
116
 
    // in the cache it didn't have any required fields.
117
 
    return false;
118
 
  }
119
 
  already_seen->insert(type);
120
 
 
121
 
  // If the type has extensions, an extension with message type could contain
122
 
  // required fields, so we have to be conservative and assume such an
123
 
  // extension exists.
124
 
  if (type->extension_range_count() > 0) return true;
125
 
 
126
 
  for (int i = 0; i < type->field_count(); i++) {
127
 
    const FieldDescriptor* field = type->field(i);
128
 
    if (field->is_required()) {
129
 
      return true;
130
 
    }
131
 
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
132
 
      if (HasRequiredFields(field->message_type(), already_seen)) {
133
 
        return true;
134
 
      }
135
 
    }
136
 
  }
137
 
 
138
 
  return false;
139
 
}
140
 
 
141
 
static bool HasRequiredFields(const Descriptor* type) {
142
 
  hash_set<const Descriptor*> already_seen;
143
 
  return HasRequiredFields(type, &already_seen);
144
 
}
145
 
 
146
 
}
147
 
 
148
 
// ===================================================================
149
 
 
150
 
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
151
 
                                   const string& dllexport_decl)
152
 
  : descriptor_(descriptor),
153
 
    classname_(ClassName(descriptor, false)),
154
 
    dllexport_decl_(dllexport_decl),
155
 
    field_generators_(descriptor),
156
 
    nested_generators_(new scoped_ptr<MessageGenerator>[
157
 
      descriptor->nested_type_count()]),
158
 
    enum_generators_(new scoped_ptr<EnumGenerator>[
159
 
      descriptor->enum_type_count()]),
160
 
    extension_generators_(new scoped_ptr<ExtensionGenerator>[
161
 
      descriptor->extension_count()]) {
162
 
 
163
 
  for (int i = 0; i < descriptor->nested_type_count(); i++) {
164
 
    nested_generators_[i].reset(
165
 
      new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
166
 
  }
167
 
 
168
 
  for (int i = 0; i < descriptor->enum_type_count(); i++) {
169
 
    enum_generators_[i].reset(
170
 
      new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
171
 
  }
172
 
 
173
 
  for (int i = 0; i < descriptor->extension_count(); i++) {
174
 
    extension_generators_[i].reset(
175
 
      new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
176
 
  }
177
 
}
178
 
 
179
 
MessageGenerator::~MessageGenerator() {}
180
 
 
181
 
void MessageGenerator::
182
 
GenerateForwardDeclaration(io::Printer* printer) {
183
 
  printer->Print("class $classname$;\n",
184
 
                 "classname", classname_);
185
 
 
186
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
187
 
    nested_generators_[i]->GenerateForwardDeclaration(printer);
188
 
  }
189
 
}
190
 
 
191
 
void MessageGenerator::
192
 
GenerateEnumDefinitions(io::Printer* printer) {
193
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
194
 
    nested_generators_[i]->GenerateEnumDefinitions(printer);
195
 
  }
196
 
 
197
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
198
 
    enum_generators_[i]->GenerateDefinition(printer);
199
 
  }
200
 
}
201
 
 
202
 
void MessageGenerator::
203
 
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
204
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
205
 
    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
206
 
  }
207
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
208
 
    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
209
 
  }
210
 
}
211
 
 
212
 
void MessageGenerator::
213
 
GenerateFieldAccessorDeclarations(io::Printer* printer) {
214
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
215
 
    const FieldDescriptor* field = descriptor_->field(i);
216
 
 
217
 
    PrintFieldComment(printer, field);
218
 
 
219
 
    map<string, string> vars;
220
 
    SetCommonFieldVariables(field, &vars);
221
 
    vars["constant_name"] = FieldConstantName(field);
222
 
 
223
 
    if (field->is_repeated()) {
224
 
      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
225
 
    } else {
226
 
      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
227
 
    }
228
 
 
229
 
    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
230
 
    printer->Print(vars, "static const int $constant_name$ = $number$;\n");
231
 
 
232
 
    // Generate type-specific accessor declarations.
233
 
    field_generators_.get(field).GenerateAccessorDeclarations(printer);
234
 
 
235
 
    printer->Print("\n");
236
 
  }
237
 
 
238
 
  if (descriptor_->extension_range_count() > 0) {
239
 
    // Generate accessors for extensions.  We just call a macro located in
240
 
    // extension_set.h since the accessors about 80 lines of static code.
241
 
    printer->Print(
242
 
      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
243
 
      "classname", classname_);
244
 
  }
245
 
}
246
 
 
247
 
void MessageGenerator::
248
 
GenerateFieldAccessorDefinitions(io::Printer* printer) {
249
 
  printer->Print("// $classname$\n\n", "classname", classname_);
250
 
 
251
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
252
 
    const FieldDescriptor* field = descriptor_->field(i);
253
 
 
254
 
    PrintFieldComment(printer, field);
255
 
 
256
 
    map<string, string> vars;
257
 
    SetCommonFieldVariables(field, &vars);
258
 
 
259
 
    // Generate has_$name$() or $name$_size().
260
 
    if (field->is_repeated()) {
261
 
      printer->Print(vars,
262
 
        "inline int $classname$::$name$_size() const {\n"
263
 
        "  return $name$_.size();\n"
264
 
        "}\n");
265
 
    } else {
266
 
      // Singular field.
267
 
      printer->Print(vars,
268
 
        "inline bool $classname$::has_$name$() const {\n"
269
 
        "  return _has_bit($index$);\n"
270
 
        "}\n");
271
 
    }
272
 
 
273
 
    // Generate clear_$name$()
274
 
    printer->Print(vars,
275
 
      "inline void $classname$::clear_$name$() {\n");
276
 
 
277
 
    printer->Indent();
278
 
    field_generators_.get(field).GenerateClearingCode(printer);
279
 
    printer->Outdent();
280
 
 
281
 
    if (!field->is_repeated()) {
282
 
      printer->Print(vars, "  _clear_bit($index$);\n");
283
 
    }
284
 
 
285
 
    printer->Print("}\n");
286
 
 
287
 
    // Generate type-specific accessors.
288
 
    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
289
 
 
290
 
    printer->Print("\n");
291
 
  }
292
 
}
293
 
 
294
 
void MessageGenerator::
295
 
GenerateClassDefinition(io::Printer* printer) {
296
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
297
 
    nested_generators_[i]->GenerateClassDefinition(printer);
298
 
    printer->Print("\n");
299
 
    printer->Print(kThinSeparator);
300
 
    printer->Print("\n");
301
 
  }
302
 
 
303
 
  map<string, string> vars;
304
 
  vars["classname"] = classname_;
305
 
  vars["field_count"] = SimpleItoa(descriptor_->field_count());
306
 
  if (dllexport_decl_.empty()) {
307
 
    vars["dllexport"] = "";
308
 
  } else {
309
 
    vars["dllexport"] = dllexport_decl_ + " ";
310
 
  }
311
 
  vars["superclass"] = SuperClassName(descriptor_);
312
 
 
313
 
  printer->Print(vars,
314
 
    "class $dllexport$$classname$ : public $superclass$ {\n"
315
 
    " public:\n");
316
 
  printer->Indent();
317
 
 
318
 
  printer->Print(vars,
319
 
    "$classname$();\n"
320
 
    "virtual ~$classname$();\n"
321
 
    "\n"
322
 
    "$classname$(const $classname$& from);\n"
323
 
    "\n"
324
 
    "inline $classname$& operator=(const $classname$& from) {\n"
325
 
    "  CopyFrom(from);\n"
326
 
    "  return *this;\n"
327
 
    "}\n"
328
 
    "\n");
329
 
 
330
 
  if (HasUnknownFields(descriptor_->file())) {
331
 
    printer->Print(
332
 
      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
333
 
      "  return _unknown_fields_;\n"
334
 
      "}\n"
335
 
      "\n"
336
 
      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
337
 
      "  return &_unknown_fields_;\n"
338
 
      "}\n"
339
 
      "\n");
340
 
  }
341
 
 
342
 
  // Only generate this member if it's not disabled.
343
 
  if (HasDescriptorMethods(descriptor_->file()) &&
344
 
      !descriptor_->options().no_standard_descriptor_accessor()) {
345
 
    printer->Print(vars,
346
 
      "static const ::google::protobuf::Descriptor* descriptor();\n");
347
 
  }
348
 
 
349
 
  printer->Print(vars,
350
 
    "static const $classname$& default_instance();\n"
351
 
    "\n");
352
 
 
353
 
 
354
 
  printer->Print(vars,
355
 
    "void Swap($classname$* other);\n"
356
 
    "\n"
357
 
    "// implements Message ----------------------------------------------\n"
358
 
    "\n"
359
 
    "$classname$* New() const;\n");
360
 
 
361
 
  if (HasGeneratedMethods(descriptor_->file())) {
362
 
    if (HasDescriptorMethods(descriptor_->file())) {
363
 
      printer->Print(vars,
364
 
        "void CopyFrom(const ::google::protobuf::Message& from);\n"
365
 
        "void MergeFrom(const ::google::protobuf::Message& from);\n");
366
 
    } else {
367
 
      printer->Print(vars,
368
 
        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
369
 
    }
370
 
 
371
 
    printer->Print(vars,
372
 
      "void CopyFrom(const $classname$& from);\n"
373
 
      "void MergeFrom(const $classname$& from);\n"
374
 
      "void Clear();\n"
375
 
      "bool IsInitialized() const;\n"
376
 
      "\n"
377
 
      "int ByteSize() const;\n"
378
 
      "bool MergePartialFromCodedStream(\n"
379
 
      "    ::google::protobuf::io::CodedInputStream* input);\n"
380
 
      "void SerializeWithCachedSizes(\n"
381
 
      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
382
 
    if (HasFastArraySerialization(descriptor_->file())) {
383
 
      printer->Print(
384
 
        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
385
 
    }
386
 
  }
387
 
 
388
 
  printer->Print(vars,
389
 
    "int GetCachedSize() const { return _cached_size_; }\n"
390
 
    "private:\n"
391
 
    "void SharedCtor();\n"
392
 
    "void SharedDtor();\n"
393
 
    "void SetCachedSize(int size) const;\n"
394
 
    "public:\n"
395
 
    "\n");
396
 
 
397
 
  if (HasDescriptorMethods(descriptor_->file())) {
398
 
    printer->Print(
399
 
      "::google::protobuf::Metadata GetMetadata() const;\n"
400
 
      "\n");
401
 
  } else {
402
 
    printer->Print(
403
 
      "::std::string GetTypeName() const;\n"
404
 
      "\n");
405
 
  }
406
 
 
407
 
  printer->Print(
408
 
    "// nested types ----------------------------------------------------\n"
409
 
    "\n");
410
 
 
411
 
  // Import all nested message classes into this class's scope with typedefs.
412
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
413
 
    const Descriptor* nested_type = descriptor_->nested_type(i);
414
 
    printer->Print("typedef $nested_full_name$ $nested_name$;\n",
415
 
                   "nested_name", nested_type->name(),
416
 
                   "nested_full_name", ClassName(nested_type, false));
417
 
  }
418
 
 
419
 
  if (descriptor_->nested_type_count() > 0) {
420
 
    printer->Print("\n");
421
 
  }
422
 
 
423
 
  // Import all nested enums and their values into this class's scope with
424
 
  // typedefs and constants.
425
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
426
 
    enum_generators_[i]->GenerateSymbolImports(printer);
427
 
    printer->Print("\n");
428
 
  }
429
 
 
430
 
  printer->Print(
431
 
    "// accessors -------------------------------------------------------\n"
432
 
    "\n");
433
 
 
434
 
  // Generate accessor methods for all fields.
435
 
  GenerateFieldAccessorDeclarations(printer);
436
 
 
437
 
  // Declare extension identifiers.
438
 
  for (int i = 0; i < descriptor_->extension_count(); i++) {
439
 
    extension_generators_[i]->GenerateDeclaration(printer);
440
 
  }
441
 
 
442
 
 
443
 
  printer->Print(
444
 
    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
445
 
    "full_name", descriptor_->full_name());
446
 
 
447
 
  // Generate private members for fields.
448
 
  printer->Outdent();
449
 
  printer->Print(" private:\n");
450
 
  printer->Indent();
451
 
 
452
 
  if (descriptor_->extension_range_count() > 0) {
453
 
    printer->Print(
454
 
      "::google::protobuf::internal::ExtensionSet _extensions_;\n");
455
 
  }
456
 
 
457
 
  if (HasUnknownFields(descriptor_->file())) {
458
 
    printer->Print(
459
 
      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
460
 
  }
461
 
 
462
 
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
463
 
  printer->Print(
464
 
    "mutable int _cached_size_;\n"
465
 
    "\n");
466
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
467
 
    field_generators_.get(descriptor_->field(i))
468
 
                     .GeneratePrivateMembers(printer);
469
 
  }
470
 
 
471
 
  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
472
 
  // friends so that they can access private static variables like
473
 
  // default_instance_ and reflection_.
474
 
  printer->Print(
475
 
    "friend void $dllexport_decl$ $adddescriptorsname$();\n",
476
 
    "dllexport_decl", dllexport_decl_,
477
 
    "adddescriptorsname",
478
 
      GlobalAddDescriptorsName(descriptor_->file()->name()));
479
 
  printer->Print(
480
 
    "friend void $assigndescriptorsname$();\n"
481
 
    "friend void $shutdownfilename$();\n"
482
 
    "\n",
483
 
    "assigndescriptorsname",
484
 
      GlobalAssignDescriptorsName(descriptor_->file()->name()),
485
 
    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
486
 
 
487
 
  // Generate offsets and _has_bits_ boilerplate.
488
 
  if (descriptor_->field_count() > 0) {
489
 
    printer->Print(vars,
490
 
      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
491
 
  } else {
492
 
    // Zero-size arrays aren't technically allowed, and MSVC in particular
493
 
    // doesn't like them.  We still need to declare these arrays to make
494
 
    // other code compile.  Since this is an uncommon case, we'll just declare
495
 
    // them with size 1 and waste some space.  Oh well.
496
 
    printer->Print(
497
 
      "::google::protobuf::uint32 _has_bits_[1];\n");
498
 
  }
499
 
 
500
 
  printer->Print(
501
 
    "\n"
502
 
    "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
503
 
    "inline bool _has_bit(int index) const {\n"
504
 
    "  return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
505
 
    "}\n"
506
 
    "inline void _set_bit(int index) {\n"
507
 
    "  _has_bits_[index / 32] |= (1u << (index % 32));\n"
508
 
    "}\n"
509
 
    "inline void _clear_bit(int index) {\n"
510
 
    "  _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
511
 
    "}\n"
512
 
    "\n"
513
 
    "void InitAsDefaultInstance();\n"
514
 
    "static $classname$* default_instance_;\n",
515
 
    "classname", classname_);
516
 
 
517
 
  printer->Outdent();
518
 
  printer->Print(vars, "};");
519
 
}
520
 
 
521
 
void MessageGenerator::
522
 
GenerateInlineMethods(io::Printer* printer) {
523
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
524
 
    nested_generators_[i]->GenerateInlineMethods(printer);
525
 
    printer->Print(kThinSeparator);
526
 
    printer->Print("\n");
527
 
  }
528
 
 
529
 
  GenerateFieldAccessorDefinitions(printer);
530
 
}
531
 
 
532
 
void MessageGenerator::
533
 
GenerateDescriptorDeclarations(io::Printer* printer) {
534
 
  printer->Print(
535
 
    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
536
 
    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
537
 
    "  $name$_reflection_ = NULL;\n",
538
 
    "name", classname_);
539
 
 
540
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
541
 
    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
542
 
  }
543
 
 
544
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
545
 
    printer->Print(
546
 
      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
547
 
      "name", ClassName(descriptor_->enum_type(i), false));
548
 
  }
549
 
}
550
 
 
551
 
void MessageGenerator::
552
 
GenerateDescriptorInitializer(io::Printer* printer, int index) {
553
 
  // TODO(kenton):  Passing the index to this method is redundant; just use
554
 
  //   descriptor_->index() instead.
555
 
  map<string, string> vars;
556
 
  vars["classname"] = classname_;
557
 
  vars["index"] = SimpleItoa(index);
558
 
 
559
 
  // Obtain the descriptor from the parent's descriptor.
560
 
  if (descriptor_->containing_type() == NULL) {
561
 
    printer->Print(vars,
562
 
      "$classname$_descriptor_ = file->message_type($index$);\n");
563
 
  } else {
564
 
    vars["parent"] = ClassName(descriptor_->containing_type(), false);
565
 
    printer->Print(vars,
566
 
      "$classname$_descriptor_ = "
567
 
        "$parent$_descriptor_->nested_type($index$);\n");
568
 
  }
569
 
 
570
 
  // Generate the offsets.
571
 
  GenerateOffsets(printer);
572
 
 
573
 
  // Construct the reflection object.
574
 
  printer->Print(vars,
575
 
    "$classname$_reflection_ =\n"
576
 
    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
577
 
    "    $classname$_descriptor_,\n"
578
 
    "    $classname$::default_instance_,\n"
579
 
    "    $classname$_offsets_,\n"
580
 
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
581
 
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
582
 
      "$classname$, _unknown_fields_),\n");
583
 
  if (descriptor_->extension_range_count() > 0) {
584
 
    printer->Print(vars,
585
 
      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
586
 
        "$classname$, _extensions_),\n");
587
 
  } else {
588
 
    // No extensions.
589
 
    printer->Print(vars,
590
 
      "    -1,\n");
591
 
  }
592
 
  printer->Print(vars,
593
 
    "    ::google::protobuf::DescriptorPool::generated_pool(),\n"
594
 
    "    ::google::protobuf::MessageFactory::generated_factory(),\n"
595
 
    "    sizeof($classname$));\n");
596
 
 
597
 
  // Handle nested types.
598
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
599
 
    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
600
 
  }
601
 
 
602
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
603
 
    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
604
 
  }
605
 
}
606
 
 
607
 
void MessageGenerator::
608
 
GenerateTypeRegistrations(io::Printer* printer) {
609
 
  // Register this message type with the message factory.
610
 
  printer->Print(
611
 
    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
612
 
    "  $classname$_descriptor_, &$classname$::default_instance());\n",
613
 
    "classname", classname_);
614
 
 
615
 
  // Handle nested types.
616
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
617
 
    nested_generators_[i]->GenerateTypeRegistrations(printer);
618
 
  }
619
 
}
620
 
 
621
 
void MessageGenerator::
622
 
GenerateDefaultInstanceAllocator(io::Printer* printer) {
623
 
  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
624
 
  // because we need to make sure all default instances that this one might
625
 
  // depend on are constructed first.
626
 
  printer->Print(
627
 
    "$classname$::default_instance_ = new $classname$();\n",
628
 
    "classname", classname_);
629
 
 
630
 
  // Handle nested types.
631
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
632
 
    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
633
 
  }
634
 
 
635
 
}
636
 
 
637
 
void MessageGenerator::
638
 
GenerateDefaultInstanceInitializer(io::Printer* printer) {
639
 
  printer->Print(
640
 
    "$classname$::default_instance_->InitAsDefaultInstance();\n",
641
 
    "classname", classname_);
642
 
 
643
 
  // Register extensions.
644
 
  for (int i = 0; i < descriptor_->extension_count(); i++) {
645
 
    extension_generators_[i]->GenerateRegistration(printer);
646
 
  }
647
 
 
648
 
  // Handle nested types.
649
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
650
 
    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
651
 
  }
652
 
}
653
 
 
654
 
void MessageGenerator::
655
 
GenerateShutdownCode(io::Printer* printer) {
656
 
  printer->Print(
657
 
    "delete $classname$::default_instance_;\n",
658
 
    "classname", classname_);
659
 
 
660
 
  if (HasDescriptorMethods(descriptor_->file())) {
661
 
    printer->Print(
662
 
      "delete $classname$_reflection_;\n",
663
 
      "classname", classname_);
664
 
  }
665
 
 
666
 
  // Handle nested types.
667
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
668
 
    nested_generators_[i]->GenerateShutdownCode(printer);
669
 
  }
670
 
}
671
 
 
672
 
void MessageGenerator::
673
 
GenerateClassMethods(io::Printer* printer) {
674
 
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
675
 
    enum_generators_[i]->GenerateMethods(printer);
676
 
  }
677
 
 
678
 
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
679
 
    nested_generators_[i]->GenerateClassMethods(printer);
680
 
    printer->Print("\n");
681
 
    printer->Print(kThinSeparator);
682
 
    printer->Print("\n");
683
 
  }
684
 
 
685
 
  // Generate non-inline field definitions.
686
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
687
 
    field_generators_.get(descriptor_->field(i))
688
 
                     .GenerateNonInlineAccessorDefinitions(printer);
689
 
  }
690
 
 
691
 
  // Generate field number constants.
692
 
  printer->Print("#ifndef _MSC_VER\n");
693
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
694
 
    const FieldDescriptor *field = descriptor_->field(i);
695
 
    printer->Print(
696
 
      "const int $classname$::$constant_name$;\n",
697
 
      "classname", ClassName(FieldScope(field), false),
698
 
      "constant_name", FieldConstantName(field));
699
 
  }
700
 
  printer->Print(
701
 
    "#endif  // !_MSC_VER\n"
702
 
    "\n");
703
 
 
704
 
  // Define extension identifiers.
705
 
  for (int i = 0; i < descriptor_->extension_count(); i++) {
706
 
    extension_generators_[i]->GenerateDefinition(printer);
707
 
  }
708
 
 
709
 
  GenerateStructors(printer);
710
 
  printer->Print("\n");
711
 
 
712
 
  if (HasGeneratedMethods(descriptor_->file())) {
713
 
    GenerateClear(printer);
714
 
    printer->Print("\n");
715
 
 
716
 
    GenerateMergeFromCodedStream(printer);
717
 
    printer->Print("\n");
718
 
 
719
 
    GenerateSerializeWithCachedSizes(printer);
720
 
    printer->Print("\n");
721
 
 
722
 
    if (HasFastArraySerialization(descriptor_->file())) {
723
 
      GenerateSerializeWithCachedSizesToArray(printer);
724
 
      printer->Print("\n");
725
 
    }
726
 
 
727
 
    GenerateByteSize(printer);
728
 
    printer->Print("\n");
729
 
 
730
 
    GenerateMergeFrom(printer);
731
 
    printer->Print("\n");
732
 
 
733
 
    GenerateCopyFrom(printer);
734
 
    printer->Print("\n");
735
 
 
736
 
    GenerateIsInitialized(printer);
737
 
    printer->Print("\n");
738
 
  }
739
 
 
740
 
  GenerateSwap(printer);
741
 
  printer->Print("\n");
742
 
 
743
 
  if (HasDescriptorMethods(descriptor_->file())) {
744
 
    printer->Print(
745
 
      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
746
 
      "  protobuf_AssignDescriptorsOnce();\n"
747
 
      "  ::google::protobuf::Metadata metadata;\n"
748
 
      "  metadata.descriptor = $classname$_descriptor_;\n"
749
 
      "  metadata.reflection = $classname$_reflection_;\n"
750
 
      "  return metadata;\n"
751
 
      "}\n"
752
 
      "\n",
753
 
      "classname", classname_);
754
 
  } else {
755
 
    printer->Print(
756
 
      "::std::string $classname$::GetTypeName() const {\n"
757
 
      "  return \"$type_name$\";\n"
758
 
      "}\n"
759
 
      "\n",
760
 
      "classname", classname_,
761
 
      "type_name", descriptor_->full_name());
762
 
  }
763
 
 
764
 
}
765
 
 
766
 
void MessageGenerator::
767
 
GenerateOffsets(io::Printer* printer) {
768
 
  printer->Print(
769
 
    "static const int $classname$_offsets_[$field_count$] = {\n",
770
 
    "classname", classname_,
771
 
    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
772
 
  printer->Indent();
773
 
 
774
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
775
 
    const FieldDescriptor* field = descriptor_->field(i);
776
 
    printer->Print(
777
 
      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
778
 
      "classname", classname_,
779
 
      "name", FieldName(field));
780
 
  }
781
 
 
782
 
  printer->Outdent();
783
 
  printer->Print("};\n");
784
 
}
785
 
 
786
 
void MessageGenerator::
787
 
GenerateSharedConstructorCode(io::Printer* printer) {
788
 
  printer->Print(
789
 
    "void $classname$::SharedCtor() {\n",
790
 
    "classname", classname_);
791
 
  printer->Indent();
792
 
 
793
 
  printer->Print(
794
 
    "_cached_size_ = 0;\n");
795
 
 
796
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
797
 
    field_generators_.get(descriptor_->field(i))
798
 
                     .GenerateConstructorCode(printer);
799
 
  }
800
 
 
801
 
  printer->Print(
802
 
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
803
 
 
804
 
  printer->Outdent();
805
 
  printer->Print("}\n\n");
806
 
}
807
 
 
808
 
void MessageGenerator::
809
 
GenerateSharedDestructorCode(io::Printer* printer) {
810
 
  printer->Print(
811
 
    "void $classname$::SharedDtor() {\n",
812
 
    "classname", classname_);
813
 
  printer->Indent();
814
 
  // Write the destructors for each field.
815
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
816
 
    field_generators_.get(descriptor_->field(i))
817
 
                     .GenerateDestructorCode(printer);
818
 
  }
819
 
 
820
 
  printer->Print(
821
 
    "if (this != default_instance_) {\n");
822
 
 
823
 
  // We need to delete all embedded messages.
824
 
  // TODO(kenton):  If we make unset messages point at default instances
825
 
  //   instead of NULL, then it would make sense to move this code into
826
 
  //   MessageFieldGenerator::GenerateDestructorCode().
827
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
828
 
    const FieldDescriptor* field = descriptor_->field(i);
829
 
 
830
 
    if (!field->is_repeated() &&
831
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
832
 
      printer->Print("  delete $name$_;\n",
833
 
                     "name", FieldName(field));
834
 
    }
835
 
  }
836
 
 
837
 
  printer->Outdent();
838
 
  printer->Print(
839
 
    "  }\n"
840
 
    "}\n"
841
 
    "\n");
842
 
}
843
 
 
844
 
void MessageGenerator::
845
 
GenerateStructors(io::Printer* printer) {
846
 
  string superclass = SuperClassName(descriptor_);
847
 
 
848
 
  // Generate the default constructor.
849
 
  printer->Print(
850
 
    "$classname$::$classname$()\n"
851
 
    "  : $superclass$() {\n"
852
 
    "  SharedCtor();\n"
853
 
    "}\n",
854
 
    "classname", classname_,
855
 
    "superclass", superclass);
856
 
 
857
 
  printer->Print(
858
 
    "\n"
859
 
    "void $classname$::InitAsDefaultInstance() {\n",
860
 
    "classname", classname_);
861
 
 
862
 
  // The default instance needs all of its embedded message pointers
863
 
  // cross-linked to other default instances.  We can't do this initialization
864
 
  // in the constructor because some other default instances may not have been
865
 
  // constructed yet at that time.
866
 
  // TODO(kenton):  Maybe all message fields (even for non-default messages)
867
 
  //   should be initialized to point at default instances rather than NULL?
868
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
869
 
    const FieldDescriptor* field = descriptor_->field(i);
870
 
 
871
 
    if (!field->is_repeated() &&
872
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
873
 
      printer->Print(
874
 
          "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
875
 
          "name", FieldName(field),
876
 
          "type", FieldMessageTypeName(field));
877
 
    }
878
 
  }
879
 
  printer->Print(
880
 
    "}\n"
881
 
    "\n");
882
 
 
883
 
  // Generate the copy constructor.
884
 
  printer->Print(
885
 
    "$classname$::$classname$(const $classname$& from)\n"
886
 
    "  : $superclass$() {\n"
887
 
    "  SharedCtor();\n"
888
 
    "  MergeFrom(from);\n"
889
 
    "}\n"
890
 
    "\n",
891
 
    "classname", classname_,
892
 
    "superclass", superclass);
893
 
 
894
 
  // Generate the shared constructor code.
895
 
  GenerateSharedConstructorCode(printer);
896
 
 
897
 
  // Generate the destructor.
898
 
  printer->Print(
899
 
    "$classname$::~$classname$() {\n"
900
 
    "  SharedDtor();\n"
901
 
    "}\n"
902
 
    "\n",
903
 
    "classname", classname_);
904
 
 
905
 
  // Generate the shared destructor code.
906
 
  GenerateSharedDestructorCode(printer);
907
 
 
908
 
  // Generate SetCachedSize.
909
 
  printer->Print(
910
 
    "void $classname$::SetCachedSize(int size) const {\n"
911
 
    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
912
 
    "  _cached_size_ = size;\n"
913
 
    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
914
 
    "}\n",
915
 
    "classname", classname_);
916
 
 
917
 
  // Only generate this member if it's not disabled.
918
 
  if (HasDescriptorMethods(descriptor_->file()) &&
919
 
      !descriptor_->options().no_standard_descriptor_accessor()) {
920
 
    printer->Print(
921
 
      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
922
 
      "  protobuf_AssignDescriptorsOnce();\n"
923
 
      "  return $classname$_descriptor_;\n"
924
 
      "}\n"
925
 
      "\n",
926
 
      "classname", classname_,
927
 
      "adddescriptorsname",
928
 
      GlobalAddDescriptorsName(descriptor_->file()->name()));
929
 
  }
930
 
 
931
 
  printer->Print(
932
 
    "const $classname$& $classname$::default_instance() {\n"
933
 
    "  if (default_instance_ == NULL) $adddescriptorsname$();"
934
 
    "  return *default_instance_;\n"
935
 
    "}\n"
936
 
    "\n"
937
 
    "$classname$* $classname$::default_instance_ = NULL;\n"
938
 
    "\n"
939
 
    "$classname$* $classname$::New() const {\n"
940
 
    "  return new $classname$;\n"
941
 
    "}\n",
942
 
    "classname", classname_,
943
 
    "adddescriptorsname",
944
 
    GlobalAddDescriptorsName(descriptor_->file()->name()));
945
 
 
946
 
}
947
 
 
948
 
void MessageGenerator::
949
 
GenerateClear(io::Printer* printer) {
950
 
  printer->Print("void $classname$::Clear() {\n",
951
 
                 "classname", classname_);
952
 
  printer->Indent();
953
 
 
954
 
  int last_index = -1;
955
 
 
956
 
  if (descriptor_->extension_range_count() > 0) {
957
 
    printer->Print("_extensions_.Clear();\n");
958
 
  }
959
 
 
960
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
961
 
    const FieldDescriptor* field = descriptor_->field(i);
962
 
 
963
 
    if (!field->is_repeated()) {
964
 
      map<string, string> vars;
965
 
      vars["index"] = SimpleItoa(field->index());
966
 
 
967
 
      // We can use the fact that _has_bits_ is a giant bitfield to our
968
 
      // advantage:  We can check up to 32 bits at a time for equality to
969
 
      // zero, and skip the whole range if so.  This can improve the speed
970
 
      // of Clear() for messages which contain a very large number of
971
 
      // optional fields of which only a few are used at a time.  Here,
972
 
      // we've chosen to check 8 bits at a time rather than 32.
973
 
      if (i / 8 != last_index / 8 || last_index < 0) {
974
 
        if (last_index >= 0) {
975
 
          printer->Outdent();
976
 
          printer->Print("}\n");
977
 
        }
978
 
        printer->Print(vars,
979
 
          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
980
 
        printer->Indent();
981
 
      }
982
 
      last_index = i;
983
 
 
984
 
      // It's faster to just overwrite primitive types, but we should
985
 
      // only clear strings and messages if they were set.
986
 
      // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
987
 
      bool should_check_bit =
988
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
989
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
990
 
 
991
 
      if (should_check_bit) {
992
 
        printer->Print(vars, "if (_has_bit($index$)) {\n");
993
 
        printer->Indent();
994
 
      }
995
 
 
996
 
      field_generators_.get(field).GenerateClearingCode(printer);
997
 
 
998
 
      if (should_check_bit) {
999
 
        printer->Outdent();
1000
 
        printer->Print("}\n");
1001
 
      }
1002
 
    }
1003
 
  }
1004
 
 
1005
 
  if (last_index >= 0) {
1006
 
    printer->Outdent();
1007
 
    printer->Print("}\n");
1008
 
  }
1009
 
 
1010
 
  // Repeated fields don't use _has_bits_ so we clear them in a separate
1011
 
  // pass.
1012
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
1013
 
    const FieldDescriptor* field = descriptor_->field(i);
1014
 
 
1015
 
    if (field->is_repeated()) {
1016
 
      field_generators_.get(field).GenerateClearingCode(printer);
1017
 
    }
1018
 
  }
1019
 
 
1020
 
  printer->Print(
1021
 
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1022
 
 
1023
 
  if (HasUnknownFields(descriptor_->file())) {
1024
 
    printer->Print(
1025
 
      "mutable_unknown_fields()->Clear();\n");
1026
 
  }
1027
 
 
1028
 
  printer->Outdent();
1029
 
  printer->Print("}\n");
1030
 
}
1031
 
 
1032
 
void MessageGenerator::
1033
 
GenerateSwap(io::Printer* printer) {
1034
 
  // Generate the Swap member function.
1035
 
  printer->Print("void $classname$::Swap($classname$* other) {\n",
1036
 
                 "classname", classname_);
1037
 
  printer->Indent();
1038
 
  printer->Print("if (other != this) {\n");
1039
 
  printer->Indent();
1040
 
 
1041
 
  if (HasGeneratedMethods(descriptor_->file())) {
1042
 
    for (int i = 0; i < descriptor_->field_count(); i++) {
1043
 
      const FieldDescriptor* field = descriptor_->field(i);
1044
 
      field_generators_.get(field).GenerateSwappingCode(printer);
1045
 
    }
1046
 
 
1047
 
    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1048
 
      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1049
 
                     "i", SimpleItoa(i));
1050
 
    }
1051
 
 
1052
 
    if (HasUnknownFields(descriptor_->file())) {
1053
 
      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1054
 
    }
1055
 
    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1056
 
    if (descriptor_->extension_range_count() > 0) {
1057
 
      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1058
 
    }
1059
 
  } else {
1060
 
    printer->Print("GetReflection()->Swap(this, other);");
1061
 
  }
1062
 
 
1063
 
  printer->Outdent();
1064
 
  printer->Print("}\n");
1065
 
  printer->Outdent();
1066
 
  printer->Print("}\n");
1067
 
}
1068
 
 
1069
 
void MessageGenerator::
1070
 
GenerateMergeFrom(io::Printer* printer) {
1071
 
  if (HasDescriptorMethods(descriptor_->file())) {
1072
 
    // Generate the generalized MergeFrom (aka that which takes in the Message
1073
 
    // base class as a parameter).
1074
 
    printer->Print(
1075
 
      "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1076
 
      "  GOOGLE_CHECK_NE(&from, this);\n",
1077
 
      "classname", classname_);
1078
 
    printer->Indent();
1079
 
 
1080
 
    // Cast the message to the proper type. If we find that the message is
1081
 
    // *not* of the proper type, we can still call Merge via the reflection
1082
 
    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1083
 
    // for each message.
1084
 
    printer->Print(
1085
 
      "const $classname$* source =\n"
1086
 
      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1087
 
      "    &from);\n"
1088
 
      "if (source == NULL) {\n"
1089
 
      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1090
 
      "} else {\n"
1091
 
      "  MergeFrom(*source);\n"
1092
 
      "}\n",
1093
 
      "classname", classname_);
1094
 
 
1095
 
    printer->Outdent();
1096
 
    printer->Print("}\n\n");
1097
 
  } else {
1098
 
    // Generate CheckTypeAndMergeFrom().
1099
 
    printer->Print(
1100
 
      "void $classname$::CheckTypeAndMergeFrom(\n"
1101
 
      "    const ::google::protobuf::MessageLite& from) {\n"
1102
 
      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1103
 
      "}\n"
1104
 
      "\n",
1105
 
      "classname", classname_);
1106
 
  }
1107
 
 
1108
 
  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1109
 
  printer->Print(
1110
 
    "void $classname$::MergeFrom(const $classname$& from) {\n"
1111
 
    "  GOOGLE_CHECK_NE(&from, this);\n",
1112
 
    "classname", classname_);
1113
 
  printer->Indent();
1114
 
 
1115
 
  // Merge Repeated fields. These fields do not require a
1116
 
  // check as we can simply iterate over them.
1117
 
  for (int i = 0; i < descriptor_->field_count(); ++i) {
1118
 
    const FieldDescriptor* field = descriptor_->field(i);
1119
 
 
1120
 
    if (field->is_repeated()) {
1121
 
      field_generators_.get(field).GenerateMergingCode(printer);
1122
 
    }
1123
 
  }
1124
 
 
1125
 
  // Merge Optional and Required fields (after a _has_bit check).
1126
 
  int last_index = -1;
1127
 
 
1128
 
  for (int i = 0; i < descriptor_->field_count(); ++i) {
1129
 
    const FieldDescriptor* field = descriptor_->field(i);
1130
 
 
1131
 
    if (!field->is_repeated()) {
1132
 
      map<string, string> vars;
1133
 
      vars["index"] = SimpleItoa(field->index());
1134
 
 
1135
 
      // See above in GenerateClear for an explanation of this.
1136
 
      if (i / 8 != last_index / 8 || last_index < 0) {
1137
 
        if (last_index >= 0) {
1138
 
          printer->Outdent();
1139
 
          printer->Print("}\n");
1140
 
        }
1141
 
        printer->Print(vars,
1142
 
          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
1143
 
        printer->Indent();
1144
 
      }
1145
 
 
1146
 
      last_index = i;
1147
 
 
1148
 
      printer->Print(vars,
1149
 
        "if (from._has_bit($index$)) {\n");
1150
 
      printer->Indent();
1151
 
 
1152
 
      field_generators_.get(field).GenerateMergingCode(printer);
1153
 
 
1154
 
      printer->Outdent();
1155
 
      printer->Print("}\n");
1156
 
    }
1157
 
  }
1158
 
 
1159
 
  if (last_index >= 0) {
1160
 
    printer->Outdent();
1161
 
    printer->Print("}\n");
1162
 
  }
1163
 
 
1164
 
  if (descriptor_->extension_range_count() > 0) {
1165
 
    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1166
 
  }
1167
 
 
1168
 
  if (HasUnknownFields(descriptor_->file())) {
1169
 
    printer->Print(
1170
 
      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1171
 
  }
1172
 
 
1173
 
  printer->Outdent();
1174
 
  printer->Print("}\n");
1175
 
}
1176
 
 
1177
 
void MessageGenerator::
1178
 
GenerateCopyFrom(io::Printer* printer) {
1179
 
  if (HasDescriptorMethods(descriptor_->file())) {
1180
 
    // Generate the generalized CopyFrom (aka that which takes in the Message
1181
 
    // base class as a parameter).
1182
 
    printer->Print(
1183
 
      "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1184
 
      "classname", classname_);
1185
 
    printer->Indent();
1186
 
 
1187
 
    printer->Print(
1188
 
      "if (&from == this) return;\n"
1189
 
      "Clear();\n"
1190
 
      "MergeFrom(from);\n");
1191
 
 
1192
 
    printer->Outdent();
1193
 
    printer->Print("}\n\n");
1194
 
  }
1195
 
 
1196
 
  // Generate the class-specific CopyFrom.
1197
 
  printer->Print(
1198
 
    "void $classname$::CopyFrom(const $classname$& from) {\n",
1199
 
    "classname", classname_);
1200
 
  printer->Indent();
1201
 
 
1202
 
  printer->Print(
1203
 
    "if (&from == this) return;\n"
1204
 
    "Clear();\n"
1205
 
    "MergeFrom(from);\n");
1206
 
 
1207
 
  printer->Outdent();
1208
 
  printer->Print("}\n");
1209
 
}
1210
 
 
1211
 
void MessageGenerator::
1212
 
GenerateMergeFromCodedStream(io::Printer* printer) {
1213
 
  if (descriptor_->options().message_set_wire_format()) {
1214
 
    // Special-case MessageSet.
1215
 
    printer->Print(
1216
 
      "bool $classname$::MergePartialFromCodedStream(\n"
1217
 
      "    ::google::protobuf::io::CodedInputStream* input) {\n"
1218
 
      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
1219
 
      "                                      mutable_unknown_fields());\n"
1220
 
      "}\n",
1221
 
      "classname", classname_);
1222
 
    return;
1223
 
  }
1224
 
 
1225
 
  printer->Print(
1226
 
    "bool $classname$::MergePartialFromCodedStream(\n"
1227
 
    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1228
 
    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1229
 
    "  ::google::protobuf::uint32 tag;\n"
1230
 
    "  while ((tag = input->ReadTag()) != 0) {\n",
1231
 
    "classname", classname_);
1232
 
 
1233
 
  printer->Indent();
1234
 
  printer->Indent();
1235
 
 
1236
 
  if (descriptor_->field_count() > 0) {
1237
 
    // We don't even want to print the switch() if we have no fields because
1238
 
    // MSVC dislikes switch() statements that contain only a default value.
1239
 
 
1240
 
    // Note:  If we just switched on the tag rather than the field number, we
1241
 
    // could avoid the need for the if() to check the wire type at the beginning
1242
 
    // of each case.  However, this is actually a bit slower in practice as it
1243
 
    // creates a jump table that is 8x larger and sparser, and meanwhile the
1244
 
    // if()s are highly predictable.
1245
 
    printer->Print(
1246
 
      "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1247
 
 
1248
 
    printer->Indent();
1249
 
 
1250
 
    scoped_array<const FieldDescriptor*> ordered_fields(
1251
 
      SortFieldsByNumber(descriptor_));
1252
 
 
1253
 
    for (int i = 0; i < descriptor_->field_count(); i++) {
1254
 
      const FieldDescriptor* field = ordered_fields[i];
1255
 
 
1256
 
      PrintFieldComment(printer, field);
1257
 
 
1258
 
      printer->Print(
1259
 
        "case $number$: {\n",
1260
 
        "number", SimpleItoa(field->number()));
1261
 
      printer->Indent();
1262
 
      const FieldGenerator& field_generator = field_generators_.get(field);
1263
 
 
1264
 
      // Emit code to parse the common, expected case.
1265
 
      printer->Print(
1266
 
        "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1267
 
        "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1268
 
        "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
1269
 
 
1270
 
      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1271
 
        printer->Print(
1272
 
          " parse_$name$:\n",
1273
 
          "name", field->name());
1274
 
      }
1275
 
 
1276
 
      printer->Indent();
1277
 
      if (field->options().packed()) {
1278
 
        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1279
 
      } else {
1280
 
        field_generator.GenerateMergeFromCodedStream(printer);
1281
 
      }
1282
 
      printer->Outdent();
1283
 
 
1284
 
      // Emit code to parse unexpectedly packed or unpacked values.
1285
 
      if (field->is_packable() && field->options().packed()) {
1286
 
        printer->Print(
1287
 
          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1288
 
          "           == ::google::protobuf::internal::WireFormatLite::\n"
1289
 
          "              WIRETYPE_$wiretype$) {\n",
1290
 
          "wiretype",
1291
 
          kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
1292
 
        printer->Indent();
1293
 
        field_generator.GenerateMergeFromCodedStream(printer);
1294
 
        printer->Outdent();
1295
 
      } else if (field->is_packable() && !field->options().packed()) {
1296
 
        printer->Print(
1297
 
          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1298
 
          "           == ::google::protobuf::internal::WireFormatLite::\n"
1299
 
          "              WIRETYPE_LENGTH_DELIMITED) {\n");
1300
 
        printer->Indent();
1301
 
        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1302
 
        printer->Outdent();
1303
 
      }
1304
 
 
1305
 
      printer->Print(
1306
 
        "} else {\n"
1307
 
        "  goto handle_uninterpreted;\n"
1308
 
        "}\n");
1309
 
 
1310
 
      // switch() is slow since it can't be predicted well.  Insert some if()s
1311
 
      // here that attempt to predict the next tag.
1312
 
      if (field->is_repeated() && !field->options().packed()) {
1313
 
        // Expect repeats of this field.
1314
 
        printer->Print(
1315
 
          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
1316
 
          "tag", SimpleItoa(WireFormat::MakeTag(field)),
1317
 
          "name", field->name());
1318
 
      }
1319
 
 
1320
 
      if (i + 1 < descriptor_->field_count()) {
1321
 
        // Expect the next field in order.
1322
 
        const FieldDescriptor* next_field = ordered_fields[i + 1];
1323
 
        printer->Print(
1324
 
          "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
1325
 
          "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
1326
 
          "next_name", next_field->name());
1327
 
      } else {
1328
 
        // Expect EOF.
1329
 
        // TODO(kenton):  Expect group end-tag?
1330
 
        printer->Print(
1331
 
          "if (input->ExpectAtEnd()) return true;\n");
1332
 
      }
1333
 
 
1334
 
      printer->Print(
1335
 
        "break;\n");
1336
 
 
1337
 
      printer->Outdent();
1338
 
      printer->Print("}\n\n");
1339
 
    }
1340
 
 
1341
 
    printer->Print(
1342
 
      "default: {\n"
1343
 
      "handle_uninterpreted:\n");
1344
 
    printer->Indent();
1345
 
  }
1346
 
 
1347
 
  // Is this an end-group tag?  If so, this must be the end of the message.
1348
 
  printer->Print(
1349
 
    "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1350
 
    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1351
 
    "  return true;\n"
1352
 
    "}\n");
1353
 
 
1354
 
  // Handle extension ranges.
1355
 
  if (descriptor_->extension_range_count() > 0) {
1356
 
    printer->Print(
1357
 
      "if (");
1358
 
    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
1359
 
      const Descriptor::ExtensionRange* range =
1360
 
        descriptor_->extension_range(i);
1361
 
      if (i > 0) printer->Print(" ||\n    ");
1362
 
 
1363
 
      uint32 start_tag = WireFormatLite::MakeTag(
1364
 
        range->start, static_cast<WireFormatLite::WireType>(0));
1365
 
      uint32 end_tag = WireFormatLite::MakeTag(
1366
 
        range->end, static_cast<WireFormatLite::WireType>(0));
1367
 
 
1368
 
      if (range->end > FieldDescriptor::kMaxNumber) {
1369
 
        printer->Print(
1370
 
          "($start$u <= tag)",
1371
 
          "start", SimpleItoa(start_tag));
1372
 
      } else {
1373
 
        printer->Print(
1374
 
          "($start$u <= tag && tag < $end$u)",
1375
 
          "start", SimpleItoa(start_tag),
1376
 
          "end", SimpleItoa(end_tag));
1377
 
      }
1378
 
    }
1379
 
    printer->Print(") {\n");
1380
 
    if (HasUnknownFields(descriptor_->file())) {
1381
 
      printer->Print(
1382
 
        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
1383
 
        "                              mutable_unknown_fields()));\n");
1384
 
    } else {
1385
 
      printer->Print(
1386
 
        "  DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
1387
 
    }
1388
 
    printer->Print(
1389
 
      "  continue;\n"
1390
 
      "}\n");
1391
 
  }
1392
 
 
1393
 
  // We really don't recognize this tag.  Skip it.
1394
 
  if (HasUnknownFields(descriptor_->file())) {
1395
 
    printer->Print(
1396
 
      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1397
 
      "      input, tag, mutable_unknown_fields()));\n");
1398
 
  } else {
1399
 
    printer->Print(
1400
 
      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
1401
 
  }
1402
 
 
1403
 
  if (descriptor_->field_count() > 0) {
1404
 
    printer->Print("break;\n");
1405
 
    printer->Outdent();
1406
 
    printer->Print("}\n");    // default:
1407
 
    printer->Outdent();
1408
 
    printer->Print("}\n");    // switch
1409
 
  }
1410
 
 
1411
 
  printer->Outdent();
1412
 
  printer->Outdent();
1413
 
  printer->Print(
1414
 
    "  }\n"                   // while
1415
 
    "  return true;\n"
1416
 
    "#undef DO_\n"
1417
 
    "}\n");
1418
 
}
1419
 
 
1420
 
void MessageGenerator::GenerateSerializeOneField(
1421
 
    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
1422
 
  PrintFieldComment(printer, field);
1423
 
 
1424
 
  if (!field->is_repeated()) {
1425
 
    printer->Print(
1426
 
      "if (_has_bit($index$)) {\n",
1427
 
      "index", SimpleItoa(field->index()));
1428
 
    printer->Indent();
1429
 
  }
1430
 
 
1431
 
  if (to_array) {
1432
 
    field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
1433
 
        printer);
1434
 
  } else {
1435
 
    field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
1436
 
  }
1437
 
 
1438
 
  if (!field->is_repeated()) {
1439
 
    printer->Outdent();
1440
 
    printer->Print("}\n");
1441
 
  }
1442
 
  printer->Print("\n");
1443
 
}
1444
 
 
1445
 
void MessageGenerator::GenerateSerializeOneExtensionRange(
1446
 
    io::Printer* printer, const Descriptor::ExtensionRange* range,
1447
 
    bool to_array) {
1448
 
  map<string, string> vars;
1449
 
  vars["start"] = SimpleItoa(range->start);
1450
 
  vars["end"] = SimpleItoa(range->end);
1451
 
  printer->Print(vars,
1452
 
    "// Extension range [$start$, $end$)\n");
1453
 
  if (to_array) {
1454
 
    printer->Print(vars,
1455
 
      "target = _extensions_.SerializeWithCachedSizesToArray(\n"
1456
 
      "    $start$, $end$, target);\n\n");
1457
 
  } else {
1458
 
    printer->Print(vars,
1459
 
      "_extensions_.SerializeWithCachedSizes(\n"
1460
 
      "    $start$, $end$, output);\n\n");
1461
 
  }
1462
 
}
1463
 
 
1464
 
void MessageGenerator::
1465
 
GenerateSerializeWithCachedSizes(io::Printer* printer) {
1466
 
  if (descriptor_->options().message_set_wire_format()) {
1467
 
    // Special-case MessageSet.
1468
 
    printer->Print(
1469
 
      "void $classname$::SerializeWithCachedSizes(\n"
1470
 
      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
1471
 
      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
1472
 
      "classname", classname_);
1473
 
    if (HasUnknownFields(descriptor_->file())) {
1474
 
      printer->Print(
1475
 
        "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
1476
 
        "      unknown_fields(), output);\n");
1477
 
    }
1478
 
    printer->Print(
1479
 
      "}\n");
1480
 
    return;
1481
 
  }
1482
 
 
1483
 
  printer->Print(
1484
 
    "void $classname$::SerializeWithCachedSizes(\n"
1485
 
    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
1486
 
    "classname", classname_);
1487
 
  printer->Indent();
1488
 
 
1489
 
  GenerateSerializeWithCachedSizesBody(printer, false);
1490
 
 
1491
 
  printer->Outdent();
1492
 
  printer->Print(
1493
 
    "}\n");
1494
 
}
1495
 
 
1496
 
void MessageGenerator::
1497
 
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
1498
 
  if (descriptor_->options().message_set_wire_format()) {
1499
 
    // Special-case MessageSet.
1500
 
    printer->Print(
1501
 
      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1502
 
      "    ::google::protobuf::uint8* target) const {\n"
1503
 
      "  target =\n"
1504
 
      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
1505
 
      "classname", classname_);
1506
 
    if (HasUnknownFields(descriptor_->file())) {
1507
 
      printer->Print(
1508
 
        "  target = ::google::protobuf::internal::WireFormat::\n"
1509
 
        "             SerializeUnknownMessageSetItemsToArray(\n"
1510
 
        "               unknown_fields(), target);\n");
1511
 
    }
1512
 
    printer->Print(
1513
 
      "  return target;\n"
1514
 
      "}\n");
1515
 
    return;
1516
 
  }
1517
 
 
1518
 
  printer->Print(
1519
 
    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1520
 
    "    ::google::protobuf::uint8* target) const {\n",
1521
 
    "classname", classname_);
1522
 
  printer->Indent();
1523
 
 
1524
 
  GenerateSerializeWithCachedSizesBody(printer, true);
1525
 
 
1526
 
  printer->Outdent();
1527
 
  printer->Print(
1528
 
    "  return target;\n"
1529
 
    "}\n");
1530
 
}
1531
 
 
1532
 
void MessageGenerator::
1533
 
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
1534
 
  scoped_array<const FieldDescriptor*> ordered_fields(
1535
 
    SortFieldsByNumber(descriptor_));
1536
 
 
1537
 
  vector<const Descriptor::ExtensionRange*> sorted_extensions;
1538
 
  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
1539
 
    sorted_extensions.push_back(descriptor_->extension_range(i));
1540
 
  }
1541
 
  sort(sorted_extensions.begin(), sorted_extensions.end(),
1542
 
       ExtensionRangeSorter());
1543
 
 
1544
 
  // Merge the fields and the extension ranges, both sorted by field number.
1545
 
  int i, j;
1546
 
  for (i = 0, j = 0;
1547
 
       i < descriptor_->field_count() || j < sorted_extensions.size();
1548
 
       ) {
1549
 
    if (i == descriptor_->field_count()) {
1550
 
      GenerateSerializeOneExtensionRange(printer,
1551
 
                                         sorted_extensions[j++],
1552
 
                                         to_array);
1553
 
    } else if (j == sorted_extensions.size()) {
1554
 
      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1555
 
    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
1556
 
      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1557
 
    } else {
1558
 
      GenerateSerializeOneExtensionRange(printer,
1559
 
                                         sorted_extensions[j++],
1560
 
                                         to_array);
1561
 
    }
1562
 
  }
1563
 
 
1564
 
  if (HasUnknownFields(descriptor_->file())) {
1565
 
    printer->Print("if (!unknown_fields().empty()) {\n");
1566
 
    printer->Indent();
1567
 
    if (to_array) {
1568
 
      printer->Print(
1569
 
        "target = "
1570
 
            "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
1571
 
        "    unknown_fields(), target);\n");
1572
 
    } else {
1573
 
      printer->Print(
1574
 
        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
1575
 
        "    unknown_fields(), output);\n");
1576
 
    }
1577
 
    printer->Outdent();
1578
 
 
1579
 
    printer->Print(
1580
 
      "}\n");
1581
 
  }
1582
 
}
1583
 
 
1584
 
void MessageGenerator::
1585
 
GenerateByteSize(io::Printer* printer) {
1586
 
  if (descriptor_->options().message_set_wire_format()) {
1587
 
    // Special-case MessageSet.
1588
 
    printer->Print(
1589
 
      "int $classname$::ByteSize() const {\n"
1590
 
      "  int total_size = _extensions_.MessageSetByteSize();\n",
1591
 
      "classname", classname_);
1592
 
    if (HasUnknownFields(descriptor_->file())) {
1593
 
      printer->Print(
1594
 
        "  total_size += ::google::protobuf::internal::WireFormat::\n"
1595
 
        "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1596
 
    }
1597
 
    printer->Print(
1598
 
      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1599
 
      "  _cached_size_ = total_size;\n"
1600
 
      "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1601
 
      "  return total_size;\n"
1602
 
      "}\n");
1603
 
    return;
1604
 
  }
1605
 
 
1606
 
  printer->Print(
1607
 
    "int $classname$::ByteSize() const {\n",
1608
 
    "classname", classname_);
1609
 
  printer->Indent();
1610
 
  printer->Print(
1611
 
    "int total_size = 0;\n"
1612
 
    "\n");
1613
 
 
1614
 
  int last_index = -1;
1615
 
 
1616
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
1617
 
    const FieldDescriptor* field = descriptor_->field(i);
1618
 
 
1619
 
    if (!field->is_repeated()) {
1620
 
      // See above in GenerateClear for an explanation of this.
1621
 
      // TODO(kenton):  Share code?  Unclear how to do so without
1622
 
      //   over-engineering.
1623
 
      if ((i / 8) != (last_index / 8) ||
1624
 
          last_index < 0) {
1625
 
        if (last_index >= 0) {
1626
 
          printer->Outdent();
1627
 
          printer->Print("}\n");
1628
 
        }
1629
 
        printer->Print(
1630
 
          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1631
 
          "index", SimpleItoa(field->index()));
1632
 
        printer->Indent();
1633
 
      }
1634
 
      last_index = i;
1635
 
 
1636
 
      PrintFieldComment(printer, field);
1637
 
 
1638
 
      printer->Print(
1639
 
        "if (has_$name$()) {\n",
1640
 
        "name", FieldName(field));
1641
 
      printer->Indent();
1642
 
 
1643
 
      field_generators_.get(field).GenerateByteSize(printer);
1644
 
 
1645
 
      printer->Outdent();
1646
 
      printer->Print(
1647
 
        "}\n"
1648
 
        "\n");
1649
 
    }
1650
 
  }
1651
 
 
1652
 
  if (last_index >= 0) {
1653
 
    printer->Outdent();
1654
 
    printer->Print("}\n");
1655
 
  }
1656
 
 
1657
 
  // Repeated fields don't use _has_bits_ so we count them in a separate
1658
 
  // pass.
1659
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
1660
 
    const FieldDescriptor* field = descriptor_->field(i);
1661
 
 
1662
 
    if (field->is_repeated()) {
1663
 
      PrintFieldComment(printer, field);
1664
 
      field_generators_.get(field).GenerateByteSize(printer);
1665
 
      printer->Print("\n");
1666
 
    }
1667
 
  }
1668
 
 
1669
 
  if (descriptor_->extension_range_count() > 0) {
1670
 
    printer->Print(
1671
 
      "total_size += _extensions_.ByteSize();\n"
1672
 
      "\n");
1673
 
  }
1674
 
 
1675
 
  if (HasUnknownFields(descriptor_->file())) {
1676
 
    printer->Print("if (!unknown_fields().empty()) {\n");
1677
 
    printer->Indent();
1678
 
    printer->Print(
1679
 
      "total_size +=\n"
1680
 
      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
1681
 
      "    unknown_fields());\n");
1682
 
    printer->Outdent();
1683
 
    printer->Print("}\n");
1684
 
  }
1685
 
 
1686
 
  // We update _cached_size_ even though this is a const method.  In theory,
1687
 
  // this is not thread-compatible, because concurrent writes have undefined
1688
 
  // results.  In practice, since any concurrent writes will be writing the
1689
 
  // exact same value, it works on all common processors.  In a future version
1690
 
  // of C++, _cached_size_ should be made into an atomic<int>.
1691
 
  printer->Print(
1692
 
    "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1693
 
    "_cached_size_ = total_size;\n"
1694
 
    "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1695
 
    "return total_size;\n");
1696
 
 
1697
 
  printer->Outdent();
1698
 
  printer->Print("}\n");
1699
 
}
1700
 
 
1701
 
void MessageGenerator::
1702
 
GenerateIsInitialized(io::Printer* printer) {
1703
 
  printer->Print(
1704
 
    "bool $classname$::IsInitialized() const {\n",
1705
 
    "classname", classname_);
1706
 
  printer->Indent();
1707
 
 
1708
 
  // Check that all required fields in this message are set.  We can do this
1709
 
  // most efficiently by checking 32 "has bits" at a time.
1710
 
  int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
1711
 
  for (int i = 0; i < has_bits_array_size; i++) {
1712
 
    uint32 mask = 0;
1713
 
    for (int bit = 0; bit < 32; bit++) {
1714
 
      int index = i * 32 + bit;
1715
 
      if (index >= descriptor_->field_count()) break;
1716
 
      const FieldDescriptor* field = descriptor_->field(index);
1717
 
 
1718
 
      if (field->is_required()) {
1719
 
        mask |= 1 << bit;
1720
 
      }
1721
 
    }
1722
 
 
1723
 
    if (mask != 0) {
1724
 
      char buffer[kFastToBufferSize];
1725
 
      printer->Print(
1726
 
        "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
1727
 
        "i", SimpleItoa(i),
1728
 
        "mask", FastHex32ToBuffer(mask, buffer));
1729
 
    }
1730
 
  }
1731
 
 
1732
 
  // Now check that all embedded messages are initialized.
1733
 
  printer->Print("\n");
1734
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
1735
 
    const FieldDescriptor* field = descriptor_->field(i);
1736
 
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1737
 
        HasRequiredFields(field->message_type())) {
1738
 
      if (field->is_repeated()) {
1739
 
        printer->Print(
1740
 
          "for (int i = 0; i < $name$_size(); i++) {\n"
1741
 
          "  if (!this->$name$(i).IsInitialized()) return false;\n"
1742
 
          "}\n",
1743
 
          "name", FieldName(field));
1744
 
      } else {
1745
 
        printer->Print(
1746
 
          "if (has_$name$()) {\n"
1747
 
          "  if (!this->$name$().IsInitialized()) return false;\n"
1748
 
          "}\n",
1749
 
          "name", FieldName(field));
1750
 
      }
1751
 
    }
1752
 
  }
1753
 
 
1754
 
  if (descriptor_->extension_range_count() > 0) {
1755
 
    printer->Print(
1756
 
      "\n"
1757
 
      "if (!_extensions_.IsInitialized()) return false;");
1758
 
  }
1759
 
 
1760
 
  printer->Outdent();
1761
 
  printer->Print(
1762
 
    "  return true;\n"
1763
 
    "}\n");
1764
 
}
1765
 
 
1766
 
 
1767
 
}  // namespace cpp
1768
 
}  // namespace compiler
1769
 
}  // namespace protobuf
1770
 
}  // namespace google