1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc. All rights reserved.
3
// http://code.google.com/p/protobuf/
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
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
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.
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.
31
// Author: kenton@google.com (Kenton Varda)
32
// Based on original Protocol Buffers design by
33
// Sanjay Ghemawat, Jeff Dean, and others.
38
#include <google/protobuf/compiler/java/java_message_field.h>
39
#include <google/protobuf/compiler/java/java_helpers.h>
40
#include <google/protobuf/io/printer.h>
41
#include <google/protobuf/wire_format.h>
42
#include <google/protobuf/stubs/strutil.h>
51
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
52
// repeat code between this and the other field types.
53
void SetMessageVariables(const FieldDescriptor* descriptor,
54
map<string, string>* variables) {
55
(*variables)["name"] =
56
UnderscoresToCamelCase(descriptor);
57
(*variables)["capitalized_name"] =
58
UnderscoresToCapitalizedCamelCase(descriptor);
59
(*variables)["number"] = SimpleItoa(descriptor->number());
60
(*variables)["type"] = ClassName(descriptor->message_type());
61
(*variables)["group_or_message"] =
62
(GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
68
// ===================================================================
70
MessageFieldGenerator::
71
MessageFieldGenerator(const FieldDescriptor* descriptor)
72
: descriptor_(descriptor) {
73
SetMessageVariables(descriptor, &variables_);
76
MessageFieldGenerator::~MessageFieldGenerator() {}
78
void MessageFieldGenerator::
79
GenerateMembers(io::Printer* printer) const {
80
printer->Print(variables_,
81
"private boolean has$capitalized_name$;\n"
82
"private $type$ $name$_;\n"
83
"public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
84
"public $type$ get$capitalized_name$() { return $name$_; }\n");
87
void MessageFieldGenerator::
88
GenerateBuilderMembers(io::Printer* printer) const {
89
printer->Print(variables_,
90
"public boolean has$capitalized_name$() {\n"
91
" return result.has$capitalized_name$();\n"
93
"public $type$ get$capitalized_name$() {\n"
94
" return result.get$capitalized_name$();\n"
96
"public Builder set$capitalized_name$($type$ value) {\n"
97
" if (value == null) {\n"
98
" throw new NullPointerException();\n"
100
" result.has$capitalized_name$ = true;\n"
101
" result.$name$_ = value;\n"
104
"public Builder set$capitalized_name$($type$.Builder builderForValue) {\n"
105
" result.has$capitalized_name$ = true;\n"
106
" result.$name$_ = builderForValue.build();\n"
109
"public Builder merge$capitalized_name$($type$ value) {\n"
110
" if (result.has$capitalized_name$() &&\n"
111
" result.$name$_ != $type$.getDefaultInstance()) {\n"
112
" result.$name$_ =\n"
113
" $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n"
115
" result.$name$_ = value;\n"
117
" result.has$capitalized_name$ = true;\n"
120
"public Builder clear$capitalized_name$() {\n"
121
" result.has$capitalized_name$ = false;\n"
122
" result.$name$_ = $type$.getDefaultInstance();\n"
127
void MessageFieldGenerator::
128
GenerateInitializationCode(io::Printer* printer) const {
129
printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
132
void MessageFieldGenerator::
133
GenerateMergingCode(io::Printer* printer) const {
134
printer->Print(variables_,
135
"if (other.has$capitalized_name$()) {\n"
136
" merge$capitalized_name$(other.get$capitalized_name$());\n"
140
void MessageFieldGenerator::
141
GenerateBuildingCode(io::Printer* printer) const {
142
// Nothing to do for singular fields.
145
void MessageFieldGenerator::
146
GenerateParsingCode(io::Printer* printer) const {
147
printer->Print(variables_,
148
"$type$.Builder subBuilder = $type$.newBuilder();\n"
149
"if (has$capitalized_name$()) {\n"
150
" subBuilder.mergeFrom(get$capitalized_name$());\n"
153
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
154
printer->Print(variables_,
155
"input.readGroup($number$, subBuilder, extensionRegistry);\n");
157
printer->Print(variables_,
158
"input.readMessage(subBuilder, extensionRegistry);\n");
161
printer->Print(variables_,
162
"set$capitalized_name$(subBuilder.buildPartial());\n");
165
void MessageFieldGenerator::
166
GenerateSerializationCode(io::Printer* printer) const {
167
printer->Print(variables_,
168
"if (has$capitalized_name$()) {\n"
169
" output.write$group_or_message$($number$, get$capitalized_name$());\n"
173
void MessageFieldGenerator::
174
GenerateSerializedSizeCode(io::Printer* printer) const {
175
printer->Print(variables_,
176
"if (has$capitalized_name$()) {\n"
177
" size += com.google.protobuf.CodedOutputStream\n"
178
" .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
182
string MessageFieldGenerator::GetBoxedType() const {
183
return ClassName(descriptor_->message_type());
186
// ===================================================================
188
RepeatedMessageFieldGenerator::
189
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
190
: descriptor_(descriptor) {
191
SetMessageVariables(descriptor, &variables_);
194
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
196
void RepeatedMessageFieldGenerator::
197
GenerateMembers(io::Printer* printer) const {
198
printer->Print(variables_,
199
"private java.util.List<$type$> $name$_ =\n"
200
" java.util.Collections.emptyList();\n"
201
"public java.util.List<$type$> get$capitalized_name$List() {\n"
202
" return $name$_;\n" // note: unmodifiable list
204
"public int get$capitalized_name$Count() { return $name$_.size(); }\n"
205
"public $type$ get$capitalized_name$(int index) {\n"
206
" return $name$_.get(index);\n"
210
void RepeatedMessageFieldGenerator::
211
GenerateBuilderMembers(io::Printer* printer) const {
212
printer->Print(variables_,
213
// Note: We return an unmodifiable list because otherwise the caller
214
// could hold on to the returned list and modify it after the message
215
// has been built, thus mutating the message which is supposed to be
217
"public java.util.List<$type$> get$capitalized_name$List() {\n"
218
" return java.util.Collections.unmodifiableList(result.$name$_);\n"
220
"public int get$capitalized_name$Count() {\n"
221
" return result.get$capitalized_name$Count();\n"
223
"public $type$ get$capitalized_name$(int index) {\n"
224
" return result.get$capitalized_name$(index);\n"
226
"public Builder set$capitalized_name$(int index, $type$ value) {\n"
227
" if (value == null) {\n"
228
" throw new NullPointerException();\n"
230
" result.$name$_.set(index, value);\n"
233
"public Builder set$capitalized_name$(int index, "
234
"$type$.Builder builderForValue) {\n"
235
" result.$name$_.set(index, builderForValue.build());\n"
238
"public Builder add$capitalized_name$($type$ value) {\n"
239
" if (value == null) {\n"
240
" throw new NullPointerException();\n"
242
" if (result.$name$_.isEmpty()) {\n"
243
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
245
" result.$name$_.add(value);\n"
248
"public Builder add$capitalized_name$($type$.Builder builderForValue) {\n"
249
" if (result.$name$_.isEmpty()) {\n"
250
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
252
" result.$name$_.add(builderForValue.build());\n"
255
"public Builder addAll$capitalized_name$(\n"
256
" java.lang.Iterable<? extends $type$> values) {\n"
257
" if (result.$name$_.isEmpty()) {\n"
258
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
260
" super.addAll(values, result.$name$_);\n"
263
"public Builder clear$capitalized_name$() {\n"
264
" result.$name$_ = java.util.Collections.emptyList();\n"
269
void RepeatedMessageFieldGenerator::
270
GenerateInitializationCode(io::Printer* printer) const {
271
// Initialized inline.
274
void RepeatedMessageFieldGenerator::
275
GenerateMergingCode(io::Printer* printer) const {
276
printer->Print(variables_,
277
"if (!other.$name$_.isEmpty()) {\n"
278
" if (result.$name$_.isEmpty()) {\n"
279
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
281
" result.$name$_.addAll(other.$name$_);\n"
285
void RepeatedMessageFieldGenerator::
286
GenerateBuildingCode(io::Printer* printer) const {
287
printer->Print(variables_,
288
"if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
289
" result.$name$_ =\n"
290
" java.util.Collections.unmodifiableList(result.$name$_);\n"
294
void RepeatedMessageFieldGenerator::
295
GenerateParsingCode(io::Printer* printer) const {
296
printer->Print(variables_,
297
"$type$.Builder subBuilder = $type$.newBuilder();\n");
299
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
300
printer->Print(variables_,
301
"input.readGroup($number$, subBuilder, extensionRegistry);\n");
303
printer->Print(variables_,
304
"input.readMessage(subBuilder, extensionRegistry);\n");
307
printer->Print(variables_,
308
"add$capitalized_name$(subBuilder.buildPartial());\n");
311
void RepeatedMessageFieldGenerator::
312
GenerateSerializationCode(io::Printer* printer) const {
313
printer->Print(variables_,
314
"for ($type$ element : get$capitalized_name$List()) {\n"
315
" output.write$group_or_message$($number$, element);\n"
319
void RepeatedMessageFieldGenerator::
320
GenerateSerializedSizeCode(io::Printer* printer) const {
321
printer->Print(variables_,
322
"for ($type$ element : get$capitalized_name$List()) {\n"
323
" size += com.google.protobuf.CodedOutputStream\n"
324
" .compute$group_or_message$Size($number$, element);\n"
328
string RepeatedMessageFieldGenerator::GetBoxedType() const {
329
return ClassName(descriptor_->message_type());
333
} // namespace compiler
334
} // namespace protobuf
335
} // namespace google