• 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/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.
SetMessageVariables(const Params & params,const FieldDescriptor * descriptor,map<string,string> * variables)56 void SetMessageVariables(const Params& params,
57     const FieldDescriptor* descriptor, map<string, string>* variables) {
58   (*variables)["name"] =
59     UnderscoresToCamelCase(descriptor);
60   (*variables)["capitalized_name"] =
61     UnderscoresToCapitalizedCamelCase(descriptor);
62   (*variables)["number"] = SimpleItoa(descriptor->number());
63   (*variables)["type"] = ClassName(params, descriptor->message_type());
64   (*variables)["group_or_message"] =
65     (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
66     "Group" : "Message";
67   (*variables)["message_name"] = descriptor->containing_type()->name();
68   //(*variables)["message_type"] = descriptor->message_type()->name();
69   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
70 }
71 
72 }  // namespace
73 
74 // ===================================================================
75 
76 MessageFieldGenerator::
MessageFieldGenerator(const FieldDescriptor * descriptor,const Params & params)77 MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
78   : FieldGenerator(params), descriptor_(descriptor) {
79   SetMessageVariables(params, descriptor, &variables_);
80 }
81 
~MessageFieldGenerator()82 MessageFieldGenerator::~MessageFieldGenerator() {}
83 
84 void MessageFieldGenerator::
GenerateMembers(io::Printer * printer) const85 GenerateMembers(io::Printer* printer) const {
86   printer->Print(variables_,
87     "public $type$ $name$ = null;\n");
88 }
89 
90 void MessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const91 GenerateParsingCode(io::Printer* printer) const {
92   printer->Print(variables_,
93     "this.$name$ = new $type$();\n");
94 
95   if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
96     printer->Print(variables_,
97       "input.readGroup(this.$name$, $number$);\n");
98   } else {
99     printer->Print(variables_,
100       "input.readMessage(this.$name$);\n");
101   }
102 }
103 
104 void MessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const105 GenerateSerializationCode(io::Printer* printer) const {
106   printer->Print(variables_,
107     "if (this.$name$ != null) {\n"
108     "  output.write$group_or_message$($number$, this.$name$);\n"
109     "}\n");
110 }
111 
112 void MessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const113 GenerateSerializedSizeCode(io::Printer* printer) const {
114   printer->Print(variables_,
115     "if (this.$name$ != null) {\n"
116     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
117     "    .compute$group_or_message$Size($number$, this.$name$);\n"
118     "}\n");
119 }
120 
GetBoxedType() const121 string MessageFieldGenerator::GetBoxedType() const {
122   return ClassName(params_, descriptor_->message_type());
123 }
124 
125 // ===================================================================
126 
127 RepeatedMessageFieldGenerator::
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Params & params)128 RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
129   : FieldGenerator(params), descriptor_(descriptor) {
130   SetMessageVariables(params, descriptor, &variables_);
131 }
132 
~RepeatedMessageFieldGenerator()133 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
134 
135 void RepeatedMessageFieldGenerator::
GenerateMembers(io::Printer * printer) const136 GenerateMembers(io::Printer* printer) const {
137   printer->Print(variables_,
138     "public $type$[] $name$ = $type$.EMPTY_ARRAY;\n");
139 }
140 
141 void RepeatedMessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const142 GenerateParsingCode(io::Printer* printer) const {
143   // First, figure out the length of the array, then parse.
144   printer->Print(variables_,
145     "int arrayLength = com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, $tag$);\n"
146     "int i = this.$name$.length;\n"
147     "this.$name$ = java.util.Arrays.copyOf(this.$name$, i + arrayLength);\n"
148     "for (; i < this.$name$.length - 1; i++) {\n"
149     "  this.$name$[i] = new $type$();\n");
150 
151   if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
152     printer->Print(variables_,
153       "  input.readGroup(this.$name$[i], $number$);\n");
154   } else {
155     printer->Print(variables_,
156       "  input.readMessage(this.$name$[i]);\n");
157   }
158 
159   printer->Print(variables_,
160     "  input.readTag();\n"
161     "}\n"
162     "// Last one without readTag.\n"
163     "this.$name$[i] = new $type$();\n");
164 
165   if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
166     printer->Print(variables_,
167       "input.readGroup(this.$name$[i], $number$);\n");
168   } else {
169     printer->Print(variables_,
170       "input.readMessage(this.$name$[i]);\n");
171   }
172 }
173 
174 void RepeatedMessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const175 GenerateSerializationCode(io::Printer* printer) const {
176   printer->Print(variables_,
177     "for ($type$ element : this.$name$) {\n"
178     "  output.write$group_or_message$($number$, element);\n"
179     "}\n");
180 }
181 
182 void RepeatedMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const183 GenerateSerializedSizeCode(io::Printer* printer) const {
184   printer->Print(variables_,
185     "for ($type$ element : this.$name$) {\n"
186     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
187     "    .compute$group_or_message$Size($number$, element);\n"
188     "}\n");
189 }
190 
GetBoxedType() const191 string RepeatedMessageFieldGenerator::GetBoxedType() const {
192   return ClassName(params_, descriptor_->message_type());
193 }
194 
195 }  // namespace javanano
196 }  // namespace compiler
197 }  // namespace protobuf
198 }  // namespace google
199