javamicro_message.cc revision e2d542951c059563a3b7f74c257dac4f222d9dc5
1e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Protocol Buffers - Google's data interchange format
2e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Copyright 2008 Google Inc.  All rights reserved.
3e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// http://code.google.com/p/protobuf/
4e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//
5e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Redistribution and use in source and binary forms, with or without
6e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// modification, are permitted provided that the following conditions are
7e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// met:
8e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//
9e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//     * Redistributions of source code must retain the above copyright
10e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// notice, this list of conditions and the following disclaimer.
11e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//     * Redistributions in binary form must reproduce the above
12e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// copyright notice, this list of conditions and the following disclaimer
13e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// in the documentation and/or other materials provided with the
14e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// distribution.
15e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//     * Neither the name of Google Inc. nor the names of its
16e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// contributors may be used to endorse or promote products derived from
17e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// this software without specific prior written permission.
18e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//
19e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
31e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Author: kenton@google.com (Kenton Varda)
32e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//  Based on original Protocol Buffers design by
33e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
35e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <algorithm>
36e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/stubs/hash.h>
37e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/compiler/javamicro/javamicro_message.h>
38e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/compiler/javamicro/javamicro_enum.h>
39e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
40e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/stubs/strutil.h>
41e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/io/printer.h>
42e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/io/coded_stream.h>
43e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/wire_format.h>
44e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#include <google/protobuf/descriptor.pb.h>
45e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
46e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillenamespace google {
47e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillenamespace protobuf {
48e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillenamespace compiler {
49e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillenamespace javamicro {
50e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
51e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savilleusing internal::WireFormat;
52e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savilleusing internal::WireFormatLite;
53e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
54e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillenamespace {
55e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
56e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
57e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Print the field's proto-syntax definition as a comment.  We don't want to
58e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // print group bodies so we cut off after the first line.
59e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  string def = field->DebugString();
60e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print("// $def$\n",
61e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "def", def.substr(0, def.find_first_of('\n')));
62e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
63e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
64e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillestruct FieldOrderingByNumber {
65e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  inline bool operator()(const FieldDescriptor* a,
66e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville                         const FieldDescriptor* b) const {
67e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    return a->number() < b->number();
68e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
69e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville};
70e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
71e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Sort the fields of the given Descriptor by number into a new[]'d array
72e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// and return it.
73e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savilleconst FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
74e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  const FieldDescriptor** fields =
75e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    new const FieldDescriptor*[descriptor->field_count()];
76e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor->field_count(); i++) {
77e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    fields[i] = descriptor->field(i);
78e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
79e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  sort(fields, fields + descriptor->field_count(),
80e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville       FieldOrderingByNumber());
81e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  return fields;
82e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
83e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
84e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Get an identifier that uniquely identifies this type within the file.
85e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// This is used to declare static variables related to this type at the
86e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// outermost file scope.
87e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillestring UniqueFileScopeIdentifier(const Descriptor* descriptor) {
88e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
89e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
90e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
91e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Returns true if the message type has any required fields.  If it doesn't,
92e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// we can optimize out calls to its isInitialized() method.
93e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville//
94e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// already_seen is used to avoid checking the same type multiple times
95e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// (and also to protect against recursion).
96e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillestatic bool HasRequiredFields(
97e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const Descriptor* type,
98e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    hash_set<const Descriptor*>* already_seen) {
99e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (already_seen->count(type) > 0) {
100e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    // The type is already in cache.  This means that either:
101e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    // a. The type has no required fields.
102e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    // b. We are in the midst of checking if the type has required fields,
103e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    //    somewhere up the stack.  In this case, we know that if the type
104e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    //    has any required fields, they'll be found when we return to it,
105e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    //    and the whole call to HasRequiredFields() will return true.
106e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    //    Therefore, we don't have to check if this type has required fields
107e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    //    here.
108e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    return false;
109e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
110e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  already_seen->insert(type);
111e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
112e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // If the type has extensions, an extension with message type could contain
113e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // required fields, so we have to be conservative and assume such an
114e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // extension exists.
115e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (type->extension_range_count() > 0) return true;
116e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
117e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < type->field_count(); i++) {
118e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = type->field(i);
119e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->is_required()) {
120e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      return true;
121e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
122e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
123e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      if (HasRequiredFields(field->message_type(), already_seen)) {
124e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        return true;
125e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      }
126e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
127e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
128e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
129e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  return false;
130e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
131e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
132e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillestatic bool HasRequiredFields(const Descriptor* type) {
133e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  hash_set<const Descriptor*> already_seen;
134e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  return HasRequiredFields(type, &already_seen);
135e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
136e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
137e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace
138e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
139e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// ===================================================================
140e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
141e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleMessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
142e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  : params_(params),
143e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    descriptor_(descriptor),
144e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_(descriptor, params) {
145e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
146e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
147e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleMessageGenerator::~MessageGenerator() {}
148e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
149e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
150e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Generate static members for all nested types.
151e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
152e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    // TODO(kenton):  Reuse MessageGenerator objects?
153e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    MessageGenerator(descriptor_->nested_type(i), params_)
154e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      .GenerateStaticVariables(printer);
155e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
156e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
157e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
158e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateStaticVariableInitializers(
159e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    io::Printer* printer) {
160e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Generate static member initializers for all nested types.
161e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
162e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    // TODO(kenton):  Reuse MessageGenerator objects?
163e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    MessageGenerator(descriptor_->nested_type(i), params_)
164e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      .GenerateStaticVariableInitializers(printer);
165e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
166e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
167e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (descriptor_->extension_count() != 0) {
168e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
169e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
170e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
171e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
172e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::Generate(io::Printer* printer) {
173e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  bool is_own_file =
174e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    params_.java_multiple_files() || ((descriptor_->containing_type() == NULL)
175e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        && !params_.has_java_outer_classname(descriptor_->file()->name()));
176e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
177e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#if 0
178e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GOOGLE_LOG(INFO) << "is_own_file=" << is_own_file;
179e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GOOGLE_LOG(INFO) << "containing_type()=" << ((descriptor_->containing_type() == NULL) ? "NULL" : "not null");
180e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GOOGLE_LOG(INFO) << "java_multiple_files()=" << params_.java_multiple_files();
181e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GOOGLE_LOG(INFO) << "has_java_outer_classname()=" << params_.has_java_outer_classname(file_->name());
182e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville#endif
183e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
184e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if ((descriptor_->extension_count() != 0)
185e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      || (descriptor_->extension_range_count() != 0)) {
186e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
187e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
188e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
189e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
190e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $modifiers$ final class $classname$ extends\n"
191e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    com.google.protobuf.micro.MessageMicro {\n",
192e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "modifiers", is_own_file ? "" : "static",
193e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
194e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
195e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
196e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $classname$() {}\n"
197e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n",
198e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
199e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
200e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Nested types and extensions
201e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
202e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
203e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
204e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
205e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
206e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
207e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
208e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
209e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Fields
210e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
211e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    PrintFieldComment(printer, descriptor_->field(i));
212e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print("public static final int $constant_name$ = $number$;\n",
213e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "constant_name", FieldConstantName(descriptor_->field(i)),
214e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "number", SimpleItoa(descriptor_->field(i)->number()));
215e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
216e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print("\n");
217e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
218e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
219e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateClear(printer);
220e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateIsInitialized(printer);
221e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateMessageSerializationMethods(printer);
222e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateMergeFromMethods(printer);
223e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateParseFromMethods(printer);
224e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
225e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
226e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print("}\n\n");
227e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
228e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
229e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// ===================================================================
230e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
231e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::
232e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleGenerateMessageSerializationMethods(io::Printer* printer) {
233e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  scoped_array<const FieldDescriptor*> sorted_fields(
234e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    SortFieldsByNumber(descriptor_));
235e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
236e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (descriptor_->extension_range_count() != 0) {
237e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
238e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
239e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
240e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
241e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output)\n"
242e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "                    throws java.io.IOException {\n");
243e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
244e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
245e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Output the fields in sorted order
246e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
247e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      GenerateSerializeOneField(printer, sorted_fields[i]);
248e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
249e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
250e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
251e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
252e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
253e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
254e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "private int cachedSize = -1;\n"
255e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public int getCachedSize() {\n"
256e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  if (cachedSize < 0) {\n"
257e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    // getSerializedSize sets cachedSize\n"
258e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    getSerializedSize();\n"
259e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"
260e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return cachedSize;\n"
261e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
262e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
263e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public int getSerializedSize() {\n"
264e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  int size = 0;\n");
265e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
266e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
267e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
268e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
269e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
270e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
271e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
272e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
273e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  cachedSize = size;\n"
274e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return size;\n"
275e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
276e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
277e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
278e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
279e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
280e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  scoped_array<const FieldDescriptor*> sorted_fields(
281e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    SortFieldsByNumber(descriptor_));
282e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
283e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (params_.java_use_vector()) {
284e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
285e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "public com.google.protobuf.micro.MessageMicro mergeFrom(\n"
286e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
287e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    throws java.io.IOException {\n",
288e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "classname", descriptor_->name());
289e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  } else {
290e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
291e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "public $classname$ mergeFrom(\n"
292e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
293e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    throws java.io.IOException {\n",
294e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "classname", descriptor_->name());
295e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
296e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
297e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
298e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
299e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "while (true) {\n");
300e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
301e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
302e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
303e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "int tag = input.readTag();\n"
304e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "switch (tag) {\n");
305e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
306e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
307e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
308e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "case 0:\n"          // zero signals EOF / limit reached
309e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return this;\n"
310e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "default: {\n"
311e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  if (!parseUnknownField(input, tag)) {\n"
312e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    return this;\n"   // it's an endgroup tag
313e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"
314e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  break;\n"
315e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n");
316e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
317e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
318e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = sorted_fields[i];
319e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    uint32 tag = WireFormatLite::MakeTag(field->number(),
320e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      WireFormat::WireTypeForField(field));
321e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
322e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
323e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "case $tag$: {\n",
324e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "tag", SimpleItoa(tag));
325e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Indent();
326e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
327e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(field).GenerateParsingCode(printer);
328e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
329e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Outdent();
330e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
331e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "  break;\n"
332e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "}\n");
333e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
334e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
335e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
336e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
337e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
338e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
339e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    }\n"     // switch (tag)
340e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"       // while (true)
341e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
342e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
343e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
344e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
345e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::
346e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleGenerateParseFromMethods(io::Printer* printer) {
347e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  bool is_own_file =
348e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    descriptor_->containing_type() == NULL;
349e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
350e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Note:  These are separate from GenerateMessageSerializationMethods()
351e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   because they need to be generated even for messages that are optimized
352e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   for code size.
353e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
354e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $static$ $classname$ parseFrom(byte[] data)\n"
355e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n"
356e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return ($classname$) (new $classname$().mergeFrom(data));\n"
357e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
358e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
359e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $static$ $classname$ parseFrom(\n"
360e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "        com.google.protobuf.micro.CodedInputStreamMicro input)\n"
361e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    throws java.io.IOException {\n"
362e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return ($classname$) (new $classname$().mergeFrom(input));\n"
363e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
364e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n",
365e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "static", (is_own_file ? "static" : ""),
366e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
367e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
368e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
369e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateSerializeOneField(
370e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    io::Printer* printer, const FieldDescriptor* field) {
371e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  field_generators_.get(field).GenerateSerializationCode(printer);
372e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
373e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
374e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateClear(io::Printer* printer) {
375e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
376e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public final $classname$ clear() {\n",
377e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
378e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
379e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
380e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Call clear for all of the fields.
381e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
382e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
383e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
384e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
385e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "clear$name$();\n",
386e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "name", UnderscoresToCapitalizedCamelCase(field));
387e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
388e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
389e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
390e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
391e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  cachedSize = -1;\n"
392e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return this;\n"
393e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
394e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
395e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
396e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
397e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
398e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
399e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
400e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public final boolean isInitialized() {\n");
401e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
402e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
403e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Check that all required fields in this message are set.
404e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // TODO(kenton):  We can optimize this when we switch to putting all the
405e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   "has" fields into a single bitfield.
406e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
407e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
408e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
409e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->is_required()) {
410e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      printer->Print(
411e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        "if (!has$name$) return false;\n",
412e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        "name", UnderscoresToCapitalizedCamelCase(field));
413e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
414e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
415e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
416e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Now check that all embedded messages are initialized.
417e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
418e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
419e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
420e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        HasRequiredFields(field->message_type())) {
421e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      switch (field->label()) {
422e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_REQUIRED:
423e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          printer->Print(
424e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "if (!get$name$().isInitialized()) return false;\n",
425e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "type", ClassName(params_, field->message_type()),
426e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "name", UnderscoresToCapitalizedCamelCase(field));
427e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
428e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_OPTIONAL:
429e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          printer->Print(
430e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "if (has$name$()) {\n"
431e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "  if (!get$name$().isInitialized()) return false;\n"
432e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "}\n",
433e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "type", ClassName(params_, field->message_type()),
434e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "name", UnderscoresToCapitalizedCamelCase(field));
435e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
436e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_REPEATED:
437e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          if (params_.java_use_vector()) {
438e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            printer->Print(
439e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "for (int i = 0; i < get$name$List().size(); i++) {\n"
440e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "  if (get$name$(i).isInitialized()) return false;\n"
441e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "}\n",
442e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "type", ClassName(params_, field->message_type()),
443e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "name", UnderscoresToCapitalizedCamelCase(field));
444e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          } else {
445e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            printer->Print(
446e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "for ($type$ element : get$name$List()) {\n"
447e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "  if (!element.isInitialized()) return false;\n"
448e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "}\n",
449e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "type", ClassName(params_, field->message_type()),
450e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "name", UnderscoresToCapitalizedCamelCase(field));
451e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          }
452e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
453e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      }
454e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
455e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
456e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
457e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (descriptor_->extension_range_count() > 0) {
458e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
459e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "if (!extensionsAreInitialized()) return false;\n");
460e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
461e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
462e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
463e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
464e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return true;\n"
465e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
466e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
467e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
468e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
469e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// ===================================================================
470e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
471e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace javamicro
472e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace compiler
473e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace protobuf
474e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace google
475