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