Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // http://code.google.com/p/protobuf/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <map>
36 : #include <string>
37 :
38 : #include <google/protobuf/compiler/javanano/javanano_message_field.h>
39 : #include <google/protobuf/compiler/javanano/javanano_helpers.h>
40 : #include <google/protobuf/io/printer.h>
41 : #include <google/protobuf/wire_format.h>
42 : #include <google/protobuf/stubs/strutil.h>
43 :
44 : namespace google {
45 : namespace protobuf {
46 : namespace compiler {
47 : namespace javanano {
48 :
49 : using internal::WireFormat;
50 : using internal::WireFormatLite;
51 :
52 : namespace {
53 :
54 : // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
55 : // repeat code between this and the other field types.
56 0 : void SetMessageVariables(const Params& params,
57 0 : const FieldDescriptor* descriptor, map<string, string>* variables) {
58 0 : (*variables)["name"] =
59 : RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
60 0 : (*variables)["capitalized_name"] =
61 : RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
62 0 : (*variables)["number"] = SimpleItoa(descriptor->number());
63 0 : (*variables)["type"] = ClassName(params, descriptor->message_type());
64 0 : (*variables)["group_or_message"] =
65 0 : (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
66 : "Group" : "Message";
67 0 : (*variables)["message_name"] = descriptor->containing_type()->name();
68 : //(*variables)["message_type"] = descriptor->message_type()->name();
69 0 : (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
70 0 : }
71 :
72 : } // namespace
73 :
74 : // ===================================================================
75 :
76 0 : MessageFieldGenerator::
77 : MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
78 0 : : FieldGenerator(params), descriptor_(descriptor) {
79 0 : SetMessageVariables(params, descriptor, &variables_);
80 0 : }
81 :
82 0 : MessageFieldGenerator::~MessageFieldGenerator() {}
83 :
84 0 : void MessageFieldGenerator::
85 : GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
86 : printer->Print(variables_,
87 0 : "public $type$ $name$;\n");
88 0 : }
89 :
90 0 : void MessageFieldGenerator::
91 : GenerateClearCode(io::Printer* printer) const {
92 : printer->Print(variables_,
93 0 : "$name$ = null;\n");
94 0 : }
95 :
96 0 : void MessageFieldGenerator::
97 : GenerateMergingCode(io::Printer* printer) const {
98 : printer->Print(variables_,
99 : "if (this.$name$ == null) {\n"
100 : " this.$name$ = new $type$();\n"
101 0 : "}\n");
102 :
103 0 : if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
104 : printer->Print(variables_,
105 0 : "input.readGroup(this.$name$, $number$);\n");
106 : } else {
107 : printer->Print(variables_,
108 0 : "input.readMessage(this.$name$);\n");
109 : }
110 0 : }
111 :
112 0 : void MessageFieldGenerator::
113 : GenerateSerializationCode(io::Printer* printer) const {
114 : printer->Print(variables_,
115 : "if (this.$name$ != null) {\n"
116 : " output.write$group_or_message$($number$, this.$name$);\n"
117 0 : "}\n");
118 0 : }
119 :
120 0 : void MessageFieldGenerator::
121 : GenerateSerializedSizeCode(io::Printer* printer) const {
122 : printer->Print(variables_,
123 : "if (this.$name$ != null) {\n"
124 : " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
125 : " .compute$group_or_message$Size($number$, this.$name$);\n"
126 0 : "}\n");
127 0 : }
128 :
129 0 : void MessageFieldGenerator::
130 : GenerateFixClonedCode(io::Printer* printer) const {
131 : printer->Print(variables_,
132 : "if (this.$name$ != null) {\n"
133 : " cloned.$name$ = this.$name$.clone();\n"
134 0 : "}\n");
135 0 : }
136 :
137 0 : void MessageFieldGenerator::
138 : GenerateEqualsCode(io::Printer* printer) const {
139 : printer->Print(variables_,
140 : "if (this.$name$ == null) { \n"
141 : " if (other.$name$ != null) {\n"
142 : " return false;\n"
143 : " }\n"
144 : "} else {\n"
145 : " if (!this.$name$.equals(other.$name$)) {\n"
146 : " return false;\n"
147 : " }\n"
148 0 : "}\n");
149 0 : }
150 :
151 0 : void MessageFieldGenerator::
152 : GenerateHashCodeCode(io::Printer* printer) const {
153 : printer->Print(variables_,
154 : "result = 31 * result +\n"
155 0 : " (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
156 0 : }
157 : // ===================================================================
158 :
159 0 : MessageOneofFieldGenerator::MessageOneofFieldGenerator(
160 : const FieldDescriptor* descriptor, const Params& params)
161 0 : : FieldGenerator(params), descriptor_(descriptor) {
162 0 : SetMessageVariables(params, descriptor, &variables_);
163 0 : SetCommonOneofVariables(descriptor, &variables_);
164 0 : }
165 :
166 0 : MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
167 :
168 0 : void MessageOneofFieldGenerator::
169 : GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
170 : printer->Print(variables_,
171 : "public boolean has$capitalized_name$() {\n"
172 : " return $has_oneof_case$;\n"
173 : "}\n"
174 : "public $type$ get$capitalized_name$() {\n"
175 : " if ($has_oneof_case$) {\n"
176 : " return ($type$) this.$oneof_name$_;\n"
177 : " }\n"
178 : " return null;\n"
179 : "}\n"
180 : "public $message_name$ set$capitalized_name$($type$ value) {\n"
181 : " if (value == null) { throw new java.lang.NullPointerException(); }\n"
182 : " $set_oneof_case$;\n"
183 : " this.$oneof_name$_ = value;\n"
184 : " return this;\n"
185 0 : "}\n");
186 0 : }
187 :
188 0 : void MessageOneofFieldGenerator::
189 : GenerateClearCode(io::Printer* printer) const {
190 : // No clear method for oneof fields.
191 0 : }
192 :
193 0 : void MessageOneofFieldGenerator::
194 : GenerateMergingCode(io::Printer* printer) const {
195 : printer->Print(variables_,
196 : "if (!($has_oneof_case$)) {\n"
197 : " this.$oneof_name$_ = new $type$();\n"
198 : "}\n"
199 : "input.readMessage(\n"
200 : " (com.google.protobuf.nano.MessageNano) this.$oneof_name$_);\n"
201 0 : "$set_oneof_case$;\n");
202 0 : }
203 :
204 0 : void MessageOneofFieldGenerator::
205 : GenerateSerializationCode(io::Printer* printer) const {
206 : printer->Print(variables_,
207 : "if ($has_oneof_case$) {\n"
208 : " output.writeMessage($number$,\n"
209 : " (com.google.protobuf.nano.MessageNano) this.$oneof_name$_);\n"
210 0 : "}\n");
211 0 : }
212 :
213 0 : void MessageOneofFieldGenerator::
214 : GenerateSerializedSizeCode(io::Printer* printer) const {
215 : printer->Print(variables_,
216 : "if ($has_oneof_case$) {\n"
217 : " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
218 : " .computeMessageSize($number$,\n"
219 : " (com.google.protobuf.nano.MessageNano) this.$oneof_name$_);\n"
220 0 : "}\n");
221 0 : }
222 :
223 0 : void MessageOneofFieldGenerator::
224 : GenerateFixClonedCode(io::Printer* printer) const {
225 : printer->Print(variables_,
226 : "if (this.$oneof_name$ != null) {\n"
227 : " cloned.$oneof_name$ = this.$oneof_name$.clone();\n"
228 0 : "}\n");
229 0 : }
230 :
231 0 : void MessageOneofFieldGenerator::
232 : GenerateEqualsCode(io::Printer* printer) const {
233 0 : GenerateOneofFieldEquals(descriptor_, variables_, printer);
234 0 : }
235 :
236 0 : void MessageOneofFieldGenerator::
237 : GenerateHashCodeCode(io::Printer* printer) const {
238 0 : GenerateOneofFieldHashCode(descriptor_, variables_, printer);
239 0 : }
240 :
241 : // ===================================================================
242 :
243 0 : RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
244 : const FieldDescriptor* descriptor, const Params& params)
245 0 : : FieldGenerator(params), descriptor_(descriptor) {
246 0 : SetMessageVariables(params, descriptor, &variables_);
247 0 : }
248 :
249 0 : RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
250 :
251 0 : void RepeatedMessageFieldGenerator::
252 : GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
253 : printer->Print(variables_,
254 0 : "public $type$[] $name$;\n");
255 0 : }
256 :
257 0 : void RepeatedMessageFieldGenerator::
258 : GenerateClearCode(io::Printer* printer) const {
259 : printer->Print(variables_,
260 0 : "$name$ = $type$.emptyArray();\n");
261 0 : }
262 :
263 0 : void RepeatedMessageFieldGenerator::
264 : GenerateMergingCode(io::Printer* printer) const {
265 : // First, figure out the length of the array, then parse.
266 : printer->Print(variables_,
267 : "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
268 : " .getRepeatedFieldArrayLength(input, $tag$);\n"
269 : "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
270 : "$type$[] newArray =\n"
271 : " new $type$[i + arrayLength];\n"
272 : "if (i != 0) {\n"
273 : " java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
274 : "}\n"
275 : "for (; i < newArray.length - 1; i++) {\n"
276 0 : " newArray[i] = new $type$();\n");
277 :
278 0 : if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
279 : printer->Print(variables_,
280 0 : " input.readGroup(newArray[i], $number$);\n");
281 : } else {
282 : printer->Print(variables_,
283 0 : " input.readMessage(newArray[i]);\n");
284 : }
285 :
286 : printer->Print(variables_,
287 : " input.readTag();\n"
288 : "}\n"
289 : "// Last one without readTag.\n"
290 0 : "newArray[i] = new $type$();\n");
291 :
292 0 : if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
293 : printer->Print(variables_,
294 0 : "input.readGroup(newArray[i], $number$);\n");
295 : } else {
296 : printer->Print(variables_,
297 0 : "input.readMessage(newArray[i]);\n");
298 : }
299 :
300 : printer->Print(variables_,
301 0 : "this.$name$ = newArray;\n");
302 0 : }
303 :
304 0 : void RepeatedMessageFieldGenerator::
305 : GenerateSerializationCode(io::Printer* printer) const {
306 : printer->Print(variables_,
307 : "if (this.$name$ != null && this.$name$.length > 0) {\n"
308 : " for (int i = 0; i < this.$name$.length; i++) {\n"
309 : " $type$ element = this.$name$[i];\n"
310 : " if (element != null) {\n"
311 : " output.write$group_or_message$($number$, element);\n"
312 : " }\n"
313 : " }\n"
314 0 : "}\n");
315 0 : }
316 :
317 0 : void RepeatedMessageFieldGenerator::
318 : GenerateSerializedSizeCode(io::Printer* printer) const {
319 : printer->Print(variables_,
320 : "if (this.$name$ != null && this.$name$.length > 0) {\n"
321 : " for (int i = 0; i < this.$name$.length; i++) {\n"
322 : " $type$ element = this.$name$[i];\n"
323 : " if (element != null) {\n"
324 : " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
325 : " .compute$group_or_message$Size($number$, element);\n"
326 : " }\n"
327 : " }\n"
328 0 : "}\n");
329 0 : }
330 :
331 0 : void RepeatedMessageFieldGenerator::
332 : GenerateFixClonedCode(io::Printer* printer) const {
333 : printer->Print(variables_,
334 : "if (this.$name$ != null && this.$name$.length > 0) {\n"
335 : " cloned.$name$ = new $type$[this.$name$.length];\n"
336 : " for (int i = 0; i < this.$name$.length; i++) {\n"
337 : " if (this.$name$[i] != null) {\n"
338 : " cloned.$name$[i] = this.$name$[i].clone();\n"
339 : " }\n"
340 : " }\n"
341 0 : "}\n");
342 0 : }
343 :
344 0 : void RepeatedMessageFieldGenerator::
345 : GenerateEqualsCode(io::Printer* printer) const {
346 : printer->Print(variables_,
347 : "if (!com.google.protobuf.nano.InternalNano.equals(\n"
348 : " this.$name$, other.$name$)) {\n"
349 : " return false;\n"
350 0 : "}\n");
351 0 : }
352 :
353 0 : void RepeatedMessageFieldGenerator::
354 : GenerateHashCodeCode(io::Printer* printer) const {
355 : printer->Print(variables_,
356 : "result = 31 * result\n"
357 0 : " + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
358 0 : }
359 :
360 : } // namespace javanano
361 : } // namespace compiler
362 : } // namespace protobuf
363 : } // namespace google
|