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 <sstream>
32 :
33 : #include <google/protobuf/compiler/code_generator.h>
34 : #include <google/protobuf/compiler/plugin.h>
35 : #include <google/protobuf/descriptor.h>
36 : #include <google/protobuf/descriptor.pb.h>
37 : #include <google/protobuf/io/printer.h>
38 : #include <google/protobuf/io/zero_copy_stream.h>
39 :
40 : #include <google/protobuf/compiler/csharp/csharp_helpers.h>
41 : #include <google/protobuf/compiler/csharp/csharp_wrapper_field.h>
42 :
43 : namespace google {
44 : namespace protobuf {
45 : namespace compiler {
46 : namespace csharp {
47 :
48 0 : WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor,
49 : int fieldOrdinal)
50 0 : : FieldGeneratorBase(descriptor, fieldOrdinal) {
51 0 : variables_["has_property_check"] = name() + "_ != null";
52 0 : variables_["has_not_property_check"] = name() + "_ == null";
53 0 : const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
54 0 : is_value_type = wrapped_field->type() != FieldDescriptor::TYPE_STRING &&
55 0 : wrapped_field->type() != FieldDescriptor::TYPE_BYTES;
56 0 : if (is_value_type) {
57 0 : variables_["nonnullable_type_name"] = type_name(wrapped_field);
58 : }
59 0 : }
60 :
61 0 : WrapperFieldGenerator::~WrapperFieldGenerator() {
62 0 : }
63 :
64 0 : void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) {
65 : printer->Print(
66 : variables_,
67 0 : "private static readonly pb::FieldCodec<$type_name$> _single_$name$_codec = ");
68 0 : GenerateCodecCode(printer);
69 : printer->Print(
70 : variables_,
71 : ";\n"
72 0 : "private $type_name$ $name$_;\n");
73 0 : AddDeprecatedFlag(printer);
74 : printer->Print(
75 : variables_,
76 : "$access_level$ $type_name$ $property_name$ {\n"
77 : " get { return $name$_; }\n"
78 : " set {\n"
79 : " $name$_ = value;\n"
80 : " }\n"
81 0 : "}\n");
82 0 : }
83 :
84 0 : void WrapperFieldGenerator::GenerateMergingCode(io::Printer* printer) {
85 : printer->Print(
86 : variables_,
87 : "if (other.$has_property_check$) {\n"
88 : " if ($has_not_property_check$ || other.$property_name$ != $default_value$) {\n"
89 : " $property_name$ = other.$property_name$;\n"
90 : " }\n"
91 0 : "}\n");
92 0 : }
93 :
94 0 : void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer) {
95 : printer->Print(
96 : variables_,
97 : "$type_name$ value = _single_$name$_codec.Read(input);\n"
98 : "if ($has_not_property_check$ || value != $default_value$) {\n"
99 : " $property_name$ = value;\n"
100 0 : "}\n");
101 0 : }
102 :
103 0 : void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
104 : printer->Print(
105 : variables_,
106 : "if ($has_property_check$) {\n"
107 : " _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n"
108 0 : "}\n");
109 0 : }
110 :
111 0 : void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
112 : printer->Print(
113 : variables_,
114 : "if ($has_property_check$) {\n"
115 : " size += _single_$name$_codec.CalculateSizeWithTag($property_name$);\n"
116 0 : "}\n");
117 0 : }
118 :
119 0 : void WrapperFieldGenerator::WriteHash(io::Printer* printer) {
120 : printer->Print(
121 : variables_,
122 0 : "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n");
123 0 : }
124 :
125 0 : void WrapperFieldGenerator::WriteEquals(io::Printer* printer) {
126 : printer->Print(
127 : variables_,
128 0 : "if ($property_name$ != other.$property_name$) return false;\n");
129 0 : }
130 :
131 0 : void WrapperFieldGenerator::WriteToString(io::Printer* printer) {
132 : // TODO: Implement if we ever actually need it...
133 0 : }
134 :
135 0 : void WrapperFieldGenerator::GenerateCloningCode(io::Printer* printer) {
136 : printer->Print(variables_,
137 0 : "$property_name$ = other.$property_name$;\n");
138 0 : }
139 :
140 0 : void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) {
141 0 : if (is_value_type) {
142 : printer->Print(
143 : variables_,
144 0 : "pb::FieldCodec.ForStructWrapper<$nonnullable_type_name$>($tag$)");
145 : } else {
146 : printer->Print(
147 : variables_,
148 0 : "pb::FieldCodec.ForClassWrapper<$type_name$>($tag$)");
149 : }
150 0 : }
151 :
152 0 : WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(const FieldDescriptor* descriptor,
153 : int fieldOrdinal)
154 0 : : WrapperFieldGenerator(descriptor, fieldOrdinal) {
155 0 : SetCommonOneofFieldVariables(&variables_);
156 0 : }
157 :
158 0 : WrapperOneofFieldGenerator::~WrapperOneofFieldGenerator() {
159 0 : }
160 :
161 0 : void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
162 : // Note: deliberately _oneof_$name$_codec, not _$oneof_name$_codec... we have one codec per field.
163 : printer->Print(
164 : variables_,
165 0 : "private static readonly pb::FieldCodec<$type_name$> _oneof_$name$_codec = ");
166 0 : GenerateCodecCode(printer);
167 0 : printer->Print(";\n");
168 0 : AddDeprecatedFlag(printer);
169 : printer->Print(
170 : variables_,
171 : "$access_level$ $type_name$ $property_name$ {\n"
172 : " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : ($type_name$) null; }\n"
173 : " set {\n"
174 : " $oneof_name$_ = value;\n"
175 : " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n"
176 : " }\n"
177 0 : "}\n");
178 0 : }
179 :
180 0 : void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
181 : printer->Print(
182 : variables_,
183 0 : "$property_name$ = _oneof_$name$_codec.Read(input);\n");
184 0 : }
185 :
186 0 : void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
187 : // TODO: I suspect this is wrong...
188 : printer->Print(
189 : variables_,
190 : "if ($has_property_check$) {\n"
191 : " _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n"
192 0 : "}\n");
193 0 : }
194 :
195 0 : void WrapperOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
196 : // TODO: I suspect this is wrong...
197 : printer->Print(
198 : variables_,
199 : "if ($has_property_check$) {\n"
200 : " size += _oneof_$name$_codec.CalculateSizeWithTag($property_name$);\n"
201 0 : "}\n");
202 0 : }
203 :
204 : } // namespace csharp
205 : } // namespace compiler
206 : } // namespace protobuf
207 : } // namespace google
|