Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
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 : #include <limits>
32 : #include <sstream>
33 :
34 : #include <google/protobuf/compiler/code_generator.h>
35 : #include <google/protobuf/compiler/plugin.h>
36 : #include <google/protobuf/descriptor.h>
37 : #include <google/protobuf/descriptor.pb.h>
38 : #include <google/protobuf/io/coded_stream.h>
39 : #include <google/protobuf/io/printer.h>
40 : #include <google/protobuf/io/zero_copy_stream.h>
41 : #include <google/protobuf/stubs/mathlimits.h>
42 : #include <google/protobuf/stubs/strutil.h>
43 : #include <google/protobuf/wire_format.h>
44 :
45 : #include <google/protobuf/compiler/csharp/csharp_field_base.h>
46 : #include <google/protobuf/compiler/csharp/csharp_helpers.h>
47 : #include <google/protobuf/compiler/csharp/csharp_names.h>
48 :
49 : using google::protobuf::internal::scoped_ptr;
50 :
51 : namespace google {
52 : namespace protobuf {
53 : namespace compiler {
54 : namespace csharp {
55 :
56 0 : void FieldGeneratorBase::SetCommonFieldVariables(
57 : map<string, string>* variables) {
58 : // Note: this will be valid even though the tag emitted for packed and unpacked versions of
59 : // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which
60 : // never effects the tag size.
61 0 : int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
62 0 : uint tag = internal::WireFormat::MakeTag(descriptor_);
63 : uint8 tag_array[5];
64 : io::CodedOutputStream::WriteTagToArray(tag, tag_array);
65 0 : string tag_bytes = SimpleItoa(tag_array[0]);
66 0 : for (int i = 1; i < tag_size; i++) {
67 0 : tag_bytes += ", " + SimpleItoa(tag_array[i]);
68 : }
69 :
70 0 : (*variables)["access_level"] = "public";
71 0 : (*variables)["tag"] = SimpleItoa(tag);
72 0 : (*variables)["tag_size"] = SimpleItoa(tag_size);
73 0 : (*variables)["tag_bytes"] = tag_bytes;
74 :
75 0 : (*variables)["property_name"] = property_name();
76 0 : (*variables)["type_name"] = type_name();
77 0 : (*variables)["name"] = name();
78 0 : (*variables)["descriptor_name"] = descriptor_->name();
79 0 : (*variables)["default_value"] = default_value();
80 0 : if (has_default_value()) {
81 0 : (*variables)["name_def_message"] =
82 0 : (*variables)["name"] + "_ = " + (*variables)["default_value"];
83 : } else {
84 0 : (*variables)["name_def_message"] = (*variables)["name"] + "_";
85 : }
86 0 : (*variables)["capitalized_type_name"] = capitalized_type_name();
87 0 : (*variables)["number"] = number();
88 0 : (*variables)["has_property_check"] =
89 0 : (*variables)["property_name"] + " != " + (*variables)["default_value"];
90 0 : (*variables)["other_has_property_check"] = "other." +
91 0 : (*variables)["property_name"] + " != " + (*variables)["default_value"];
92 0 : }
93 :
94 0 : void FieldGeneratorBase::SetCommonOneofFieldVariables(
95 : map<string, string>* variables) {
96 0 : (*variables)["oneof_name"] = oneof_name();
97 0 : (*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() +
98 0 : "OneofCase." + property_name();
99 0 : (*variables)["oneof_property_name"] = oneof_property_name();
100 0 : }
101 :
102 0 : FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
103 : int fieldOrdinal)
104 : : SourceGeneratorBase(descriptor->file()),
105 : descriptor_(descriptor),
106 0 : fieldOrdinal_(fieldOrdinal) {
107 0 : SetCommonFieldVariables(&variables_);
108 0 : }
109 :
110 0 : FieldGeneratorBase::~FieldGeneratorBase() {
111 0 : }
112 :
113 0 : void FieldGeneratorBase::GenerateFreezingCode(io::Printer* printer) {
114 : // No-op: only message fields and repeated fields need
115 : // special handling for freezing, so default to not generating any code.
116 0 : }
117 :
118 0 : void FieldGeneratorBase::GenerateCodecCode(io::Printer* printer) {
119 : // No-op: expect this to be overridden by appropriate types.
120 : // Could fail if we get called here though...
121 0 : }
122 :
123 0 : void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) {
124 0 : if (descriptor_->options().deprecated())
125 : {
126 0 : printer->Print("[global::System.ObsoleteAttribute()]\n");
127 : }
128 0 : }
129 :
130 0 : void FieldGeneratorBase::AddPublicMemberAttributes(io::Printer* printer) {
131 0 : AddDeprecatedFlag(printer);
132 0 : }
133 :
134 0 : std::string FieldGeneratorBase::oneof_property_name() {
135 0 : return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), true);
136 : }
137 :
138 0 : std::string FieldGeneratorBase::oneof_name() {
139 0 : return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), false);
140 : }
141 :
142 0 : std::string FieldGeneratorBase::property_name() {
143 0 : return GetPropertyName(descriptor_);
144 : }
145 :
146 0 : std::string FieldGeneratorBase::name() {
147 0 : return UnderscoresToCamelCase(GetFieldName(descriptor_), false);
148 : }
149 :
150 0 : std::string FieldGeneratorBase::type_name() {
151 0 : return type_name(descriptor_);
152 : }
153 :
154 0 : std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
155 0 : switch (descriptor->type()) {
156 : case FieldDescriptor::TYPE_ENUM:
157 0 : return GetClassName(descriptor->enum_type());
158 : case FieldDescriptor::TYPE_MESSAGE:
159 : case FieldDescriptor::TYPE_GROUP:
160 0 : if (IsWrapperType(descriptor)) {
161 0 : const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
162 0 : string wrapped_field_type_name = type_name(wrapped_field);
163 : // String and ByteString go to the same type; other wrapped types go to the
164 : // nullable equivalent.
165 0 : if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
166 0 : wrapped_field->type() == FieldDescriptor::TYPE_BYTES) {
167 0 : return wrapped_field_type_name;
168 : } else {
169 0 : return wrapped_field_type_name + "?";
170 : }
171 : }
172 0 : return GetClassName(descriptor->message_type());
173 : case FieldDescriptor::TYPE_DOUBLE:
174 0 : return "double";
175 : case FieldDescriptor::TYPE_FLOAT:
176 0 : return "float";
177 : case FieldDescriptor::TYPE_INT64:
178 0 : return "long";
179 : case FieldDescriptor::TYPE_UINT64:
180 0 : return "ulong";
181 : case FieldDescriptor::TYPE_INT32:
182 0 : return "int";
183 : case FieldDescriptor::TYPE_FIXED64:
184 0 : return "ulong";
185 : case FieldDescriptor::TYPE_FIXED32:
186 0 : return "uint";
187 : case FieldDescriptor::TYPE_BOOL:
188 0 : return "bool";
189 : case FieldDescriptor::TYPE_STRING:
190 0 : return "string";
191 : case FieldDescriptor::TYPE_BYTES:
192 0 : return "pb::ByteString";
193 : case FieldDescriptor::TYPE_UINT32:
194 0 : return "uint";
195 : case FieldDescriptor::TYPE_SFIXED32:
196 0 : return "int";
197 : case FieldDescriptor::TYPE_SFIXED64:
198 0 : return "long";
199 : case FieldDescriptor::TYPE_SINT32:
200 0 : return "int";
201 : case FieldDescriptor::TYPE_SINT64:
202 0 : return "long";
203 : default:
204 0 : GOOGLE_LOG(FATAL)<< "Unknown field type.";
205 0 : return "";
206 : }
207 : }
208 :
209 0 : bool FieldGeneratorBase::has_default_value() {
210 0 : switch (descriptor_->type()) {
211 : case FieldDescriptor::TYPE_ENUM:
212 : case FieldDescriptor::TYPE_MESSAGE:
213 : case FieldDescriptor::TYPE_GROUP:
214 : return true;
215 : case FieldDescriptor::TYPE_DOUBLE:
216 0 : return descriptor_->default_value_double() != 0.0;
217 : case FieldDescriptor::TYPE_FLOAT:
218 0 : return descriptor_->default_value_float() != 0.0;
219 : case FieldDescriptor::TYPE_INT64:
220 0 : return descriptor_->default_value_int64() != 0L;
221 : case FieldDescriptor::TYPE_UINT64:
222 0 : return descriptor_->default_value_uint64() != 0L;
223 : case FieldDescriptor::TYPE_INT32:
224 0 : return descriptor_->default_value_int32() != 0;
225 : case FieldDescriptor::TYPE_FIXED64:
226 0 : return descriptor_->default_value_uint64() != 0L;
227 : case FieldDescriptor::TYPE_FIXED32:
228 0 : return descriptor_->default_value_uint32() != 0;
229 : case FieldDescriptor::TYPE_BOOL:
230 0 : return descriptor_->default_value_bool();
231 : case FieldDescriptor::TYPE_STRING:
232 : return true;
233 : case FieldDescriptor::TYPE_BYTES:
234 : return true;
235 : case FieldDescriptor::TYPE_UINT32:
236 0 : return descriptor_->default_value_uint32() != 0;
237 : case FieldDescriptor::TYPE_SFIXED32:
238 0 : return descriptor_->default_value_int32() != 0;
239 : case FieldDescriptor::TYPE_SFIXED64:
240 0 : return descriptor_->default_value_int64() != 0L;
241 : case FieldDescriptor::TYPE_SINT32:
242 0 : return descriptor_->default_value_int32() != 0;
243 : case FieldDescriptor::TYPE_SINT64:
244 0 : return descriptor_->default_value_int64() != 0L;
245 : default:
246 0 : GOOGLE_LOG(FATAL)<< "Unknown field type.";
247 0 : return true;
248 : }
249 : }
250 :
251 0 : bool FieldGeneratorBase::is_nullable_type() {
252 0 : switch (descriptor_->type()) {
253 : case FieldDescriptor::TYPE_ENUM:
254 : case FieldDescriptor::TYPE_DOUBLE:
255 : case FieldDescriptor::TYPE_FLOAT:
256 : case FieldDescriptor::TYPE_INT64:
257 : case FieldDescriptor::TYPE_UINT64:
258 : case FieldDescriptor::TYPE_INT32:
259 : case FieldDescriptor::TYPE_FIXED64:
260 : case FieldDescriptor::TYPE_FIXED32:
261 : case FieldDescriptor::TYPE_BOOL:
262 : case FieldDescriptor::TYPE_UINT32:
263 : case FieldDescriptor::TYPE_SFIXED32:
264 : case FieldDescriptor::TYPE_SFIXED64:
265 : case FieldDescriptor::TYPE_SINT32:
266 : case FieldDescriptor::TYPE_SINT64:
267 : return false;
268 :
269 : case FieldDescriptor::TYPE_MESSAGE:
270 : case FieldDescriptor::TYPE_GROUP:
271 : case FieldDescriptor::TYPE_STRING:
272 : case FieldDescriptor::TYPE_BYTES:
273 : return true;
274 :
275 : default:
276 0 : GOOGLE_LOG(FATAL)<< "Unknown field type.";
277 0 : return true;
278 : }
279 : }
280 :
281 0 : bool AllPrintableAscii(const std::string& text) {
282 0 : for(int i = 0; i < text.size(); i++) {
283 0 : if (text[i] < 0x20 || text[i] > 0x7e) {
284 : return false;
285 : }
286 : }
287 : return true;
288 : }
289 :
290 0 : std::string FieldGeneratorBase::GetStringDefaultValueInternal() {
291 : // No other default values needed for proto3...
292 0 : return "\"\"";
293 : }
294 :
295 0 : std::string FieldGeneratorBase::GetBytesDefaultValueInternal() {
296 : // No other default values needed for proto3...
297 0 : return "pb::ByteString.Empty";
298 : }
299 :
300 0 : std::string FieldGeneratorBase::default_value() {
301 0 : return default_value(descriptor_);
302 : }
303 :
304 0 : std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor) {
305 0 : switch (descriptor->type()) {
306 : case FieldDescriptor::TYPE_ENUM:
307 0 : return type_name() + "." + descriptor->default_value_enum()->name();
308 : case FieldDescriptor::TYPE_MESSAGE:
309 : case FieldDescriptor::TYPE_GROUP:
310 0 : if (IsWrapperType(descriptor)) {
311 0 : const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
312 0 : return default_value(wrapped_field);
313 : } else {
314 0 : return "null";
315 : }
316 : case FieldDescriptor::TYPE_DOUBLE: {
317 0 : double value = descriptor->default_value_double();
318 0 : if (value == numeric_limits<double>::infinity()) {
319 0 : return "double.PositiveInfinity";
320 0 : } else if (value == -numeric_limits<double>::infinity()) {
321 0 : return "double.NegativeInfinity";
322 0 : } else if (MathLimits<double>::IsNaN(value)) {
323 0 : return "double.NaN";
324 : }
325 0 : return SimpleDtoa(value) + "D";
326 : }
327 : case FieldDescriptor::TYPE_FLOAT: {
328 0 : float value = descriptor->default_value_float();
329 0 : if (value == numeric_limits<float>::infinity()) {
330 0 : return "float.PositiveInfinity";
331 0 : } else if (value == -numeric_limits<float>::infinity()) {
332 0 : return "float.NegativeInfinity";
333 0 : } else if (MathLimits<float>::IsNaN(value)) {
334 0 : return "float.NaN";
335 : }
336 0 : return SimpleFtoa(value) + "F";
337 : }
338 : case FieldDescriptor::TYPE_INT64:
339 0 : return SimpleItoa(descriptor->default_value_int64()) + "L";
340 : case FieldDescriptor::TYPE_UINT64:
341 0 : return SimpleItoa(descriptor->default_value_uint64()) + "UL";
342 : case FieldDescriptor::TYPE_INT32:
343 0 : return SimpleItoa(descriptor->default_value_int32());
344 : case FieldDescriptor::TYPE_FIXED64:
345 0 : return SimpleItoa(descriptor->default_value_uint64()) + "UL";
346 : case FieldDescriptor::TYPE_FIXED32:
347 0 : return SimpleItoa(descriptor->default_value_uint32());
348 : case FieldDescriptor::TYPE_BOOL:
349 0 : if (descriptor->default_value_bool()) {
350 0 : return "true";
351 : } else {
352 0 : return "false";
353 : }
354 : case FieldDescriptor::TYPE_STRING:
355 0 : return GetStringDefaultValueInternal();
356 : case FieldDescriptor::TYPE_BYTES:
357 0 : return GetBytesDefaultValueInternal();
358 : case FieldDescriptor::TYPE_UINT32:
359 0 : return SimpleItoa(descriptor->default_value_uint32());
360 : case FieldDescriptor::TYPE_SFIXED32:
361 0 : return SimpleItoa(descriptor->default_value_int32());
362 : case FieldDescriptor::TYPE_SFIXED64:
363 0 : return SimpleItoa(descriptor->default_value_int64()) + "L";
364 : case FieldDescriptor::TYPE_SINT32:
365 0 : return SimpleItoa(descriptor->default_value_int32());
366 : case FieldDescriptor::TYPE_SINT64:
367 0 : return SimpleItoa(descriptor->default_value_int64()) + "L";
368 : default:
369 0 : GOOGLE_LOG(FATAL)<< "Unknown field type.";
370 0 : return "";
371 : }
372 : }
373 :
374 0 : std::string FieldGeneratorBase::number() {
375 0 : return SimpleItoa(descriptor_->number());
376 : }
377 :
378 0 : std::string FieldGeneratorBase::capitalized_type_name() {
379 0 : switch (descriptor_->type()) {
380 : case FieldDescriptor::TYPE_ENUM:
381 0 : return "Enum";
382 : case FieldDescriptor::TYPE_MESSAGE:
383 0 : return "Message";
384 : case FieldDescriptor::TYPE_GROUP:
385 0 : return "Group";
386 : case FieldDescriptor::TYPE_DOUBLE:
387 0 : return "Double";
388 : case FieldDescriptor::TYPE_FLOAT:
389 0 : return "Float";
390 : case FieldDescriptor::TYPE_INT64:
391 0 : return "Int64";
392 : case FieldDescriptor::TYPE_UINT64:
393 0 : return "UInt64";
394 : case FieldDescriptor::TYPE_INT32:
395 0 : return "Int32";
396 : case FieldDescriptor::TYPE_FIXED64:
397 0 : return "Fixed64";
398 : case FieldDescriptor::TYPE_FIXED32:
399 0 : return "Fixed32";
400 : case FieldDescriptor::TYPE_BOOL:
401 0 : return "Bool";
402 : case FieldDescriptor::TYPE_STRING:
403 0 : return "String";
404 : case FieldDescriptor::TYPE_BYTES:
405 0 : return "Bytes";
406 : case FieldDescriptor::TYPE_UINT32:
407 0 : return "UInt32";
408 : case FieldDescriptor::TYPE_SFIXED32:
409 0 : return "SFixed32";
410 : case FieldDescriptor::TYPE_SFIXED64:
411 0 : return "SFixed64";
412 : case FieldDescriptor::TYPE_SINT32:
413 0 : return "SInt32";
414 : case FieldDescriptor::TYPE_SINT64:
415 0 : return "SInt64";
416 : default:
417 0 : GOOGLE_LOG(FATAL)<< "Unknown field type.";
418 0 : return "";
419 : }
420 : }
421 :
422 : } // namespace csharp
423 : } // namespace compiler
424 : } // namespace protobuf
425 : } // namespace google
|