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
18925b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  // Note: Fields (which will be emitted in the loop, below) may have the same names as fields in
19025b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  // the inner or outer class.  This causes Java warnings, but is not fatal, so we suppress those
19125b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  // warnings here in the class declaration.
192e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
19325b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    "@SuppressWarnings(\"hiding\")\n"
194e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $modifiers$ final class $classname$ extends\n"
195e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    com.google.protobuf.micro.MessageMicro {\n",
196e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "modifiers", is_own_file ? "" : "static",
197e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
198e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
199e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
200e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $classname$() {}\n"
201e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n",
202e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
203e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
204e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Nested types and extensions
205e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
206e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
207e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
208e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
209e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
210e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
211e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
212e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
213e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Fields
214e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
215e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    PrintFieldComment(printer, descriptor_->field(i));
216e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print("public static final int $constant_name$ = $number$;\n",
217e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "constant_name", FieldConstantName(descriptor_->field(i)),
218e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "number", SimpleItoa(descriptor_->field(i)->number()));
219e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
220e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print("\n");
221e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
222e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
223e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateClear(printer);
224e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateIsInitialized(printer);
225e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateMessageSerializationMethods(printer);
226e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateMergeFromMethods(printer);
227e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  GenerateParseFromMethods(printer);
228e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
229e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
230e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print("}\n\n");
231e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
232e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
233e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// ===================================================================
234e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
235e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::
236e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleGenerateMessageSerializationMethods(io::Printer* printer) {
237e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  scoped_array<const FieldDescriptor*> sorted_fields(
238e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    SortFieldsByNumber(descriptor_));
239e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
240e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (descriptor_->extension_range_count() != 0) {
241e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
242e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
243e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
24425b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  // writeTo only throws an exception if it contains one or more fields to write
24525b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  if (descriptor_->field_count() > 0) {
24625b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    printer->Print(
24725b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "@Override\n"
24825b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output)\n"
24925b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "                    throws java.io.IOException {\n");
25025b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  } else {
25125b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    printer->Print(
25225b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "@Override\n"
25325b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output) {\n");
25425b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler  }
255e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
256e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
257e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Output the fields in sorted order
258e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
259e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      GenerateSerializeOneField(printer, sorted_fields[i]);
260e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
261e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
262e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
263e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
264e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
265e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
266e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "private int cachedSize = -1;\n"
26725b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    "@Override\n"
268e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public int getCachedSize() {\n"
269e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  if (cachedSize < 0) {\n"
270e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    // getSerializedSize sets cachedSize\n"
271e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    getSerializedSize();\n"
272e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"
273e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return cachedSize;\n"
274e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
275e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
27625b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    "@Override\n"
277e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public int getSerializedSize() {\n"
278e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  int size = 0;\n");
279e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
280e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
281e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
282e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
283e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
284e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
285e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
286e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
287e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  cachedSize = size;\n"
288e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return size;\n"
289e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
290e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
291e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
292e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
293e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
294e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  scoped_array<const FieldDescriptor*> sorted_fields(
295e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    SortFieldsByNumber(descriptor_));
296e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
297e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (params_.java_use_vector()) {
298e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
29925b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "@Override\n"
300e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "public com.google.protobuf.micro.MessageMicro mergeFrom(\n"
301e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
302e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    throws java.io.IOException {\n",
303e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "classname", descriptor_->name());
304e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  } else {
305e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
30625b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler      "@Override\n"
307e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "public $classname$ mergeFrom(\n"
308e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
309e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "    throws java.io.IOException {\n",
310e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "classname", descriptor_->name());
311e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
312e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
313e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
314e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
315e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "while (true) {\n");
316e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
317e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
318e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
319e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "int tag = input.readTag();\n"
320e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "switch (tag) {\n");
321e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
322e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
323e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
324e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "case 0:\n"          // zero signals EOF / limit reached
325e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return this;\n"
326e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "default: {\n"
327e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  if (!parseUnknownField(input, tag)) {\n"
328e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    return this;\n"   // it's an endgroup tag
329e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"
330e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  break;\n"
331e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n");
332e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
333e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
334e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = sorted_fields[i];
335e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    uint32 tag = WireFormatLite::MakeTag(field->number(),
336e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      WireFormat::WireTypeForField(field));
337e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
338e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
339e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "case $tag$: {\n",
340e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "tag", SimpleItoa(tag));
341e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Indent();
342e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
343e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    field_generators_.get(field).GenerateParsingCode(printer);
344e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
345e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Outdent();
346e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
347e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "  break;\n"
348e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "}\n");
349e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
350e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
351e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
352e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
353e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
354e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
355e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    }\n"     // switch (tag)
356e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  }\n"       // while (true)
357e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
358e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
359e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
360e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
361e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::
362e2d542951c059563a3b7f74c257dac4f222d9dc5Wink SavilleGenerateParseFromMethods(io::Printer* printer) {
363e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  bool is_own_file =
364e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    descriptor_->containing_type() == NULL;
365e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
366e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Note:  These are separate from GenerateMessageSerializationMethods()
367e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   because they need to be generated even for messages that are optimized
368e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   for code size.
369e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
370e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $static$ $classname$ parseFrom(byte[] data)\n"
371e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n"
372e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return ($classname$) (new $classname$().mergeFrom(data));\n"
373e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
374e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n"
375e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public $static$ $classname$ parseFrom(\n"
376e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "        com.google.protobuf.micro.CodedInputStreamMicro input)\n"
377e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "    throws java.io.IOException {\n"
37825b5a76155860b450c1176684f8e6007aab8aa7bAndy Stadler    "  return new $classname$().mergeFrom(input);\n"
379e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
380e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n",
381e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "static", (is_own_file ? "static" : ""),
382e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
383e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
384e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
385e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateSerializeOneField(
386e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    io::Printer* printer, const FieldDescriptor* field) {
387e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  field_generators_.get(field).GenerateSerializationCode(printer);
388e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
389e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
390e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateClear(io::Printer* printer) {
391e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
392e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public final $classname$ clear() {\n",
393e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "classname", descriptor_->name());
394e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
395e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
396e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Call clear for all of the fields.
397e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
398e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
399e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
400e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
401e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "clear$name$();\n",
402e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "name", UnderscoresToCapitalizedCamelCase(field));
403e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
404e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
405e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
406e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
407e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  cachedSize = -1;\n"
408e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return this;\n"
409e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
410e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
411e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
412e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
413e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
414e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillevoid MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
415e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
416e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "public final boolean isInitialized() {\n");
417e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Indent();
418e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
419e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Check that all required fields in this message are set.
420e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // TODO(kenton):  We can optimize this when we switch to putting all the
421e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  //   "has" fields into a single bitfield.
422e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
423e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
424e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
425e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->is_required()) {
426e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      printer->Print(
427e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        "if (!has$name$) return false;\n",
428e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        "name", UnderscoresToCapitalizedCamelCase(field));
429e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
430e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
431e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
432e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  // Now check that all embedded messages are initialized.
433e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
434e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    const FieldDescriptor* field = descriptor_->field(i);
435e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
436e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        HasRequiredFields(field->message_type())) {
437e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      switch (field->label()) {
438e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_REQUIRED:
439e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          printer->Print(
440e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "if (!get$name$().isInitialized()) return false;\n",
441e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "type", ClassName(params_, field->message_type()),
442e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "name", UnderscoresToCapitalizedCamelCase(field));
443e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
444e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_OPTIONAL:
445e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          printer->Print(
446e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "if (has$name$()) {\n"
447e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "  if (!get$name$().isInitialized()) return false;\n"
448e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "}\n",
449e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "type", ClassName(params_, field->message_type()),
450e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            "name", UnderscoresToCapitalizedCamelCase(field));
451e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
452e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville        case FieldDescriptor::LABEL_REPEATED:
453e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          if (params_.java_use_vector()) {
454e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            printer->Print(
455e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "for (int i = 0; i < get$name$List().size(); i++) {\n"
456e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "  if (get$name$(i).isInitialized()) return false;\n"
457e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "}\n",
458e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "type", ClassName(params_, field->message_type()),
459e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "name", UnderscoresToCapitalizedCamelCase(field));
460e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          } else {
461e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville            printer->Print(
462e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "for ($type$ element : get$name$List()) {\n"
463e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "  if (!element.isInitialized()) return false;\n"
464e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "}\n",
465e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "type", ClassName(params_, field->message_type()),
466e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville              "name", UnderscoresToCapitalizedCamelCase(field));
467e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          }
468e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville          break;
469e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      }
470e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    }
471e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
472e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
473e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  if (descriptor_->extension_range_count() > 0) {
474e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    printer->Print(
475e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville      "if (!extensionsAreInitialized()) return false;\n");
476e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  }
477e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
478e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Outdent();
479e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville  printer->Print(
480e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "  return true;\n"
481e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "}\n"
482e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville    "\n");
483e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}
484e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
485e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// ===================================================================
486e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville
487e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace javamicro
488e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace compiler
489e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace protobuf
490e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville}  // namespace google
491