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