csharp_message_field.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. #include <sstream>
  31. #include <google/protobuf/compiler/code_generator.h>
  32. #include <google/protobuf/compiler/plugin.h>
  33. #include <google/protobuf/descriptor.h>
  34. #include <google/protobuf/descriptor.pb.h>
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/io/zero_copy_stream.h>
  37. #include <google/protobuf/stubs/strutil.h>
  38. #include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
  39. #include <google/protobuf/compiler/csharp/csharp_helpers.h>
  40. #include <google/protobuf/compiler/csharp/csharp_message_field.h>
  41. #include <google/protobuf/compiler/csharp/csharp_options.h>
  42. namespace google {
  43. namespace protobuf {
  44. namespace compiler {
  45. namespace csharp {
  46. MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
  47. int fieldOrdinal,
  48. const Options *options)
  49. : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
  50. variables_["has_property_check"] = name() + "_ != null";
  51. variables_["has_not_property_check"] = name() + "_ == null";
  52. }
  53. MessageFieldGenerator::~MessageFieldGenerator() {
  54. }
  55. void MessageFieldGenerator::GenerateMembers(io::Printer* printer) {
  56. printer->Print(
  57. variables_,
  58. "private $type_name$ $name$_;\n");
  59. WritePropertyDocComment(printer, descriptor_);
  60. AddDeprecatedFlag(printer);
  61. printer->Print(
  62. variables_,
  63. "$access_level$ $type_name$ $property_name$ {\n"
  64. " get { return $name$_; }\n"
  65. " set {\n"
  66. " $name$_ = value;\n"
  67. " }\n"
  68. "}\n");
  69. }
  70. void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
  71. printer->Print(
  72. variables_,
  73. "if (other.$has_property_check$) {\n"
  74. " if ($has_not_property_check$) {\n"
  75. " $name$_ = new $type_name$();\n"
  76. " }\n"
  77. " $property_name$.MergeFrom(other.$property_name$);\n"
  78. "}\n");
  79. }
  80. void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
  81. printer->Print(
  82. variables_,
  83. "if ($has_not_property_check$) {\n"
  84. " $name$_ = new $type_name$();\n"
  85. "}\n"
  86. // TODO(jonskeet): Do we really need merging behaviour like this?
  87. "input.ReadMessage($name$_);\n"); // No need to support TYPE_GROUP...
  88. }
  89. void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
  90. printer->Print(
  91. variables_,
  92. "if ($has_property_check$) {\n"
  93. " output.WriteRawTag($tag_bytes$);\n"
  94. " output.WriteMessage($property_name$);\n"
  95. "}\n");
  96. }
  97. void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
  98. printer->Print(
  99. variables_,
  100. "if ($has_property_check$) {\n"
  101. " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n"
  102. "}\n");
  103. }
  104. void MessageFieldGenerator::WriteHash(io::Printer* printer) {
  105. printer->Print(
  106. variables_,
  107. "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n");
  108. }
  109. void MessageFieldGenerator::WriteEquals(io::Printer* printer) {
  110. printer->Print(
  111. variables_,
  112. "if (!object.Equals($property_name$, other.$property_name$)) return false;\n");
  113. }
  114. void MessageFieldGenerator::WriteToString(io::Printer* printer) {
  115. variables_["field_name"] = GetFieldName(descriptor_);
  116. printer->Print(
  117. variables_,
  118. "PrintField(\"$field_name$\", has$property_name$, $name$_, writer);\n");
  119. }
  120. void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) {
  121. printer->Print(variables_,
  122. "$property_name$ = other.$has_property_check$ ? other.$property_name$.Clone() : null;\n");
  123. }
  124. void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
  125. }
  126. void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) {
  127. printer->Print(
  128. variables_,
  129. "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
  130. }
  131. MessageOneofFieldGenerator::MessageOneofFieldGenerator(
  132. const FieldDescriptor* descriptor,
  133. int fieldOrdinal,
  134. const Options *options)
  135. : MessageFieldGenerator(descriptor, fieldOrdinal, options) {
  136. SetCommonOneofFieldVariables(&variables_);
  137. }
  138. MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
  139. }
  140. void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
  141. WritePropertyDocComment(printer, descriptor_);
  142. AddDeprecatedFlag(printer);
  143. printer->Print(
  144. variables_,
  145. "$access_level$ $type_name$ $property_name$ {\n"
  146. " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n"
  147. " set {\n"
  148. " $oneof_name$_ = value;\n"
  149. " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n"
  150. " }\n"
  151. "}\n");
  152. }
  153. void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
  154. // TODO(jonskeet): We may be able to do better than this
  155. printer->Print(
  156. variables_,
  157. "$type_name$ subBuilder = new $type_name$();\n"
  158. "if ($has_property_check$) {\n"
  159. " subBuilder.MergeFrom($property_name$);\n"
  160. "}\n"
  161. "input.ReadMessage(subBuilder);\n" // No support of TYPE_GROUP
  162. "$property_name$ = subBuilder;\n");
  163. }
  164. void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) {
  165. printer->Print(
  166. variables_,
  167. "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n");
  168. }
  169. void MessageOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) {
  170. printer->Print(variables_,
  171. "$property_name$ = other.$property_name$.Clone();\n");
  172. }
  173. } // namespace csharp
  174. } // namespace compiler
  175. } // namespace protobuf
  176. } // namespace google