• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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>
43 
44 namespace google {
45 namespace protobuf {
46 namespace compiler {
47 namespace java {
48 
49 namespace {
50 
51 // TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
52 //   repeat code between this and the other field types.
SetMessageVariables(const FieldDescriptor * descriptor,map<string,string> * variables)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) ?
63     "Group" : "Message";
64 }
65 
66 }  // namespace
67 
68 // ===================================================================
69 
70 MessageFieldGenerator::
MessageFieldGenerator(const FieldDescriptor * descriptor)71 MessageFieldGenerator(const FieldDescriptor* descriptor)
72   : descriptor_(descriptor) {
73   SetMessageVariables(descriptor, &variables_);
74 }
75 
~MessageFieldGenerator()76 MessageFieldGenerator::~MessageFieldGenerator() {}
77 
78 void MessageFieldGenerator::
GenerateMembers(io::Printer * printer) const79 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");
85 }
86 
87 void MessageFieldGenerator::
GenerateBuilderMembers(io::Printer * printer) const88 GenerateBuilderMembers(io::Printer* printer) const {
89   printer->Print(variables_,
90     "public boolean has$capitalized_name$() {\n"
91     "  return result.has$capitalized_name$();\n"
92     "}\n"
93     "public $type$ get$capitalized_name$() {\n"
94     "  return result.get$capitalized_name$();\n"
95     "}\n"
96     "public Builder set$capitalized_name$($type$ value) {\n"
97     "  if (value == null) {\n"
98     "    throw new NullPointerException();\n"
99     "  }\n"
100     "  result.has$capitalized_name$ = true;\n"
101     "  result.$name$_ = value;\n"
102     "  return this;\n"
103     "}\n"
104     "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n"
105     "  result.has$capitalized_name$ = true;\n"
106     "  result.$name$_ = builderForValue.build();\n"
107     "  return this;\n"
108     "}\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"
114     "  } else {\n"
115     "    result.$name$_ = value;\n"
116     "  }\n"
117     "  result.has$capitalized_name$ = true;\n"
118     "  return this;\n"
119     "}\n"
120     "public Builder clear$capitalized_name$() {\n"
121     "  result.has$capitalized_name$ = false;\n"
122     "  result.$name$_ = $type$.getDefaultInstance();\n"
123     "  return this;\n"
124     "}\n");
125 }
126 
127 void MessageFieldGenerator::
GenerateInitializationCode(io::Printer * printer) const128 GenerateInitializationCode(io::Printer* printer) const {
129   printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
130 }
131 
132 void MessageFieldGenerator::
GenerateMergingCode(io::Printer * printer) const133 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"
137     "}\n");
138 }
139 
140 void MessageFieldGenerator::
GenerateBuildingCode(io::Printer * printer) const141 GenerateBuildingCode(io::Printer* printer) const {
142   // Nothing to do for singular fields.
143 }
144 
145 void MessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const146 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"
151     "}\n");
152 
153   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
154     printer->Print(variables_,
155       "input.readGroup($number$, subBuilder, extensionRegistry);\n");
156   } else {
157     printer->Print(variables_,
158       "input.readMessage(subBuilder, extensionRegistry);\n");
159   }
160 
161   printer->Print(variables_,
162     "set$capitalized_name$(subBuilder.buildPartial());\n");
163 }
164 
165 void MessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const166 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"
170     "}\n");
171 }
172 
173 void MessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const174 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"
179     "}\n");
180 }
181 
GetBoxedType() const182 string MessageFieldGenerator::GetBoxedType() const {
183   return ClassName(descriptor_->message_type());
184 }
185 
186 // ===================================================================
187 
188 RepeatedMessageFieldGenerator::
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor)189 RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
190   : descriptor_(descriptor) {
191   SetMessageVariables(descriptor, &variables_);
192 }
193 
~RepeatedMessageFieldGenerator()194 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
195 
196 void RepeatedMessageFieldGenerator::
GenerateMembers(io::Printer * printer) const197 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
203     "}\n"
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"
207     "}\n");
208 }
209 
210 void RepeatedMessageFieldGenerator::
GenerateBuilderMembers(io::Printer * printer) const211 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
216     //   immutable.
217     "public java.util.List<$type$> get$capitalized_name$List() {\n"
218     "  return java.util.Collections.unmodifiableList(result.$name$_);\n"
219     "}\n"
220     "public int get$capitalized_name$Count() {\n"
221     "  return result.get$capitalized_name$Count();\n"
222     "}\n"
223     "public $type$ get$capitalized_name$(int index) {\n"
224     "  return result.get$capitalized_name$(index);\n"
225     "}\n"
226     "public Builder set$capitalized_name$(int index, $type$ value) {\n"
227     "  if (value == null) {\n"
228     "    throw new NullPointerException();\n"
229     "  }\n"
230     "  result.$name$_.set(index, value);\n"
231     "  return this;\n"
232     "}\n"
233     "public Builder set$capitalized_name$(int index, "
234       "$type$.Builder builderForValue) {\n"
235     "  result.$name$_.set(index, builderForValue.build());\n"
236     "  return this;\n"
237     "}\n"
238     "public Builder add$capitalized_name$($type$ value) {\n"
239     "  if (value == null) {\n"
240     "    throw new NullPointerException();\n"
241     "  }\n"
242     "  if (result.$name$_.isEmpty()) {\n"
243     "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
244     "  }\n"
245     "  result.$name$_.add(value);\n"
246     "  return this;\n"
247     "}\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"
251     "  }\n"
252     "  result.$name$_.add(builderForValue.build());\n"
253     "  return this;\n"
254     "}\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"
259     "  }\n"
260     "  super.addAll(values, result.$name$_);\n"
261     "  return this;\n"
262     "}\n"
263     "public Builder clear$capitalized_name$() {\n"
264     "  result.$name$_ = java.util.Collections.emptyList();\n"
265     "  return this;\n"
266     "}\n");
267 }
268 
269 void RepeatedMessageFieldGenerator::
GenerateInitializationCode(io::Printer * printer) const270 GenerateInitializationCode(io::Printer* printer) const {
271   // Initialized inline.
272 }
273 
274 void RepeatedMessageFieldGenerator::
GenerateMergingCode(io::Printer * printer) const275 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"
280     "  }\n"
281     "  result.$name$_.addAll(other.$name$_);\n"
282     "}\n");
283 }
284 
285 void RepeatedMessageFieldGenerator::
GenerateBuildingCode(io::Printer * printer) const286 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"
291     "}\n");
292 }
293 
294 void RepeatedMessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const295 GenerateParsingCode(io::Printer* printer) const {
296   printer->Print(variables_,
297     "$type$.Builder subBuilder = $type$.newBuilder();\n");
298 
299   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
300     printer->Print(variables_,
301       "input.readGroup($number$, subBuilder, extensionRegistry);\n");
302   } else {
303     printer->Print(variables_,
304       "input.readMessage(subBuilder, extensionRegistry);\n");
305   }
306 
307   printer->Print(variables_,
308     "add$capitalized_name$(subBuilder.buildPartial());\n");
309 }
310 
311 void RepeatedMessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const312 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"
316     "}\n");
317 }
318 
319 void RepeatedMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const320 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"
325     "}\n");
326 }
327 
GetBoxedType() const328 string RepeatedMessageFieldGenerator::GetBoxedType() const {
329   return ClassName(descriptor_->message_type());
330 }
331 
332 }  // namespace java
333 }  // namespace compiler
334 }  // namespace protobuf
335 }  // namespace google
336