csharp_reflection_class.cc
Go to the documentation of this file.
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 
39 
40 
48 
49 namespace google {
50 namespace protobuf {
51 namespace compiler {
52 namespace csharp {
53 
55  const Options* options)
57  file_(file) {
61 }
62 
64 }
65 
67  WriteIntroduction(printer);
68 
69  WriteDescriptor(printer);
70  // Close the class declaration.
71  printer->Outdent();
72  printer->Print("}\n");
73 
74  if (file_->extension_count() > 0) {
75  printer->Print(
76  "/// <summary>Holder for extension identifiers generated from the top level of $file_name$</summary>\n"
77  "internal static partial class $class_name$ {\n",
78  "access_level", class_access_level(),
79  "class_name", extensionClassname_,
80  "file_name", file_->name());
81  printer->Indent();
82  for (int i = 0; i < file_->extension_count(); i++) {
83  std::unique_ptr<FieldGeneratorBase> generator(
84  CreateFieldGenerator(file_->extension(i), -1, this->options()));
85  generator->GenerateExtensionCode(printer);
86  }
87  printer->Outdent();
88  printer->Print(
89  "}\n"
90  "\n");
91  }
92 
93  // write children: Enums
94  if (file_->enum_type_count() > 0) {
95  printer->Print("#region Enums\n");
96  for (int i = 0; i < file_->enum_type_count(); i++) {
97  EnumGenerator enumGenerator(file_->enum_type(i), this->options());
98  enumGenerator.Generate(printer);
99  }
100  printer->Print("#endregion\n");
101  printer->Print("\n");
102  }
103 
104  // write children: Messages
105  if (file_->message_type_count() > 0) {
106  printer->Print("#region Messages\n");
107  for (int i = 0; i < file_->message_type_count(); i++) {
108  MessageGenerator messageGenerator(file_->message_type(i), this->options());
109  messageGenerator.Generate(printer);
110  }
111  printer->Print("#endregion\n");
112  printer->Print("\n");
113  }
114 
115  // TODO(jtattermusch): add insertion point for services.
116 
117  if (!namespace_.empty()) {
118  printer->Outdent();
119  printer->Print("}\n");
120  }
121  printer->Print("\n");
122  printer->Print("#endregion Designer generated code\n");
123 }
124 
126  printer->Print(
127  "// <auto-generated>\n"
128  "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
129  "// source: $file_name$\n"
130  "// </auto-generated>\n"
131  "#pragma warning disable 1591, 0612, 3021\n"
132  "#region Designer generated code\n"
133  "\n"
134  "using pb = global::Google.Protobuf;\n"
135  "using pbc = global::Google.Protobuf.Collections;\n"
136  "using pbr = global::Google.Protobuf.Reflection;\n"
137  "using scg = global::System.Collections.Generic;\n",
138  "file_name", file_->name());
139 
140  if (!namespace_.empty()) {
141  printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
142  printer->Indent();
143  printer->Print("\n");
144  }
145 
146  printer->Print(
147  "/// <summary>Holder for reflection information generated from $file_name$</summary>\n"
148  "$access_level$ static partial class $reflection_class_name$ {\n"
149  "\n",
150  "file_name", file_->name(),
151  "access_level", class_access_level(),
152  "reflection_class_name", reflectionClassname_);
153  printer->Indent();
154 }
155 
157  printer->Print(
158  "#region Descriptor\n"
159  "/// <summary>File descriptor for $file_name$</summary>\n"
160  "public static pbr::FileDescriptor Descriptor {\n"
161  " get { return descriptor; }\n"
162  "}\n"
163  "private static pbr::FileDescriptor descriptor;\n"
164  "\n"
165  "static $reflection_class_name$() {\n",
166  "file_name", file_->name(),
167  "reflection_class_name", reflectionClassname_);
168  printer->Indent();
169  printer->Print(
170  "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
171  printer->Indent();
172  printer->Indent();
173  printer->Print("string.Concat(\n");
174  printer->Indent();
175 
176  // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
178  while (base64.size() > 60) {
179  printer->Print("\"$base64$\",\n", "base64", base64.substr(0, 60));
180  base64 = base64.substr(60);
181  }
182  printer->Print("\"$base64$\"));\n", "base64", base64);
183  printer->Outdent();
184  printer->Outdent();
185  printer->Outdent();
186 
187  // -----------------------------------------------------------------
188  // Invoke InternalBuildGeneratedFileFrom() to build the file.
189  printer->Print(
190  "descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,\n");
191  printer->Print(" new pbr::FileDescriptor[] { ");
192  for (int i = 0; i < file_->dependency_count(); i++) {
193  printer->Print(
194  "$full_reflection_class_name$.Descriptor, ",
195  "full_reflection_class_name",
197  }
198  printer->Print("},\n"
199  " new pbr::GeneratedClrTypeInfo(");
200  // Specify all the generated code information, recursively.
201  if (file_->enum_type_count() > 0) {
202  printer->Print("new[] {");
203  for (int i = 0; i < file_->enum_type_count(); i++) {
204  printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i)));
205  }
206  printer->Print("}, ");
207  }
208  else {
209  printer->Print("null, ");
210  }
211  if (file_->extension_count() > 0) {
212  std::vector<std::string> extensions;
213  for (int i = 0; i < file_->extension_count(); i++) {
214  extensions.push_back(GetFullExtensionName(file_->extension(i)));
215  }
216  printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", JoinStrings(extensions, ", "));
217  }
218  else {
219  printer->Print("null, ");
220  }
221  if (file_->message_type_count() > 0) {
222  printer->Print("new pbr::GeneratedClrTypeInfo[] {\n");
223  printer->Indent();
224  printer->Indent();
225  printer->Indent();
226  for (int i = 0; i < file_->message_type_count(); i++) {
228  }
229  printer->Outdent();
230  printer->Print("\n}));\n");
231  printer->Outdent();
232  printer->Outdent();
233  }
234  else {
235  printer->Print("null));\n");
236  }
237 
238  printer->Outdent();
239  printer->Print("}\n");
240  printer->Print("#endregion\n\n");
241 }
242 
243 // Write out the generated code for a particular message. This consists of the CLR type, property names
244 // corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part
245 // can be specified as null if it would be empty, to make the generated code somewhat simpler to read.
246 // We write a line break at the end of each generated code info, so that in the final file we'll see all
247 // the types, pre-ordered depth first, one per line. The indentation will be slightly unusual,
248 // in that it will look like a single array when it's actually constructing a tree, but it'll be easy to
249 // read even with multiple levels of nesting.
250 // The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate
251 // context. It governs whether or not a trailing comma and newline is written after the constructor, effectively
252 // just controlling the formatting in the generated code.
255  printer->Print("null, ");
256  return;
257  }
258  // Generated message type
259  printer->Print("new pbr::GeneratedClrTypeInfo(typeof($type_name$), $type_name$.Parser, ", "type_name", GetClassName(descriptor));
260 
261  // Fields
262  if (descriptor->field_count() > 0) {
263  std::vector<std::string> fields;
264  for (int i = 0; i < descriptor->field_count(); i++) {
265  fields.push_back(GetPropertyName(descriptor->field(i)));
266  }
267  printer->Print("new[]{ \"$fields$\" }, ", "fields", JoinStrings(fields, "\", \""));
268  }
269  else {
270  printer->Print("null, ");
271  }
272 
273  // Oneofs
274  if (descriptor->oneof_decl_count() > 0) {
275  std::vector<std::string> oneofs;
276  for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
277  oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
278  }
279  printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", JoinStrings(oneofs, "\", \""));
280  }
281  else {
282  printer->Print("null, ");
283  }
284 
285  // Nested enums
286  if (descriptor->enum_type_count() > 0) {
287  std::vector<std::string> enums;
288  for (int i = 0; i < descriptor->enum_type_count(); i++) {
289  enums.push_back(GetClassName(descriptor->enum_type(i)));
290  }
291  printer->Print("new[]{ typeof($enums$) }, ", "enums", JoinStrings(enums, "), typeof("));
292  }
293  else {
294  printer->Print("null, ");
295  }
296 
297  // Extensions
298  if (descriptor->extension_count() > 0) {
299  std::vector<std::string> extensions;
300  for (int i = 0; i < descriptor->extension_count(); i++) {
301  extensions.push_back(GetFullExtensionName(descriptor->extension(i)));
302  }
303  printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", JoinStrings(extensions, ", "));
304  }
305  else {
306  printer->Print("null, ");
307  }
308 
309  // Nested types
310  if (descriptor->nested_type_count() > 0) {
311  // Need to specify array type explicitly here, as all elements may be null.
312  printer->Print("new pbr::GeneratedClrTypeInfo[] { ");
313  for (int i = 0; i < descriptor->nested_type_count(); i++) {
314  WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
315  }
316  printer->Print("}");
317  }
318  else {
319  printer->Print("null");
320  }
321  printer->Print(last ? ")" : "),\n");
322 }
323 
324 } // namespace csharp
325 } // namespace compiler
326 } // namespace protobuf
327 } // namespace google
enums
static const upb_enumdef enums[5]
Definition: ruby/ext/google/protobuf_c/upb.c:7672
zero_copy_stream.h
google::protobuf::io::Printer::Print
void Print(const std::map< std::string, std::string > &variables, const char *text)
Definition: printer.cc:112
google::protobuf::FieldDescriptor::options
const FieldOptions & options() const
google::protobuf::FileDescriptor::enum_type
const EnumDescriptor * enum_type(int index) const
google::protobuf::compiler::csharp::ReflectionClassGenerator::namespace_
std::string namespace_
Definition: csharp_reflection_class.h:59
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
google::protobuf::compiler::csharp::GetFileNamespace
std::string GetFileNamespace(const FileDescriptor *descriptor)
Definition: csharp_helpers.cc:114
google::protobuf::compiler::csharp::GetFullExtensionName
std::string GetFullExtensionName(const FieldDescriptor *descriptor)
Definition: csharp_helpers.cc:324
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
csharp_enum.h
google::protobuf::compiler::csharp::ReflectionClassGenerator::extensionClassname_
std::string extensionClassname_
Definition: csharp_reflection_class.h:61
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::compiler::csharp::EnumGenerator::Generate
void Generate(io::Printer *printer)
Definition: csharp_enum.cc:58
google::protobuf::FileDescriptor::enum_type_count
int enum_type_count() const
google::protobuf::Descriptor::options
const MessageOptions & options() const
google::protobuf::compiler::csharp::Options
Definition: csharp_options.h:42
google::protobuf::io::Printer::Indent
void Indent()
Definition: printer.cc:185
base64
strutil.h
google::protobuf::compiler::csharp::ReflectionClassGenerator::WriteGeneratedCodeInfo
void WriteGeneratedCodeInfo(const Descriptor *descriptor, io::Printer *printer, bool last)
Definition: csharp_reflection_class.cc:253
csharp_reflection_class.h
google::protobuf::compiler::csharp::GetReflectionClassUnqualifiedName
std::string GetReflectionClassUnqualifiedName(const FileDescriptor *descriptor)
Definition: csharp_helpers.cc:130
google::protobuf::compiler::csharp::MessageGenerator
Definition: csharp_message.h:48
printer.h
google::protobuf::compiler::csharp::ReflectionClassGenerator::WriteIntroduction
void WriteIntroduction(io::Printer *printer)
Definition: csharp_reflection_class.cc:125
google::protobuf::compiler::csharp::ReflectionClassGenerator::Generate
void Generate(io::Printer *printer)
Definition: csharp_reflection_class.cc:66
google::protobuf::compiler::csharp::ReflectionClassGenerator::~ReflectionClassGenerator
~ReflectionClassGenerator()
Definition: csharp_reflection_class.cc:63
code_generator.h
google::protobuf::compiler::csharp::MessageGenerator::Generate
void Generate(io::Printer *printer)
Definition: csharp_message.cc:116
google::protobuf::compiler::csharp::GetPropertyName
std::string GetPropertyName(const FieldDescriptor *descriptor)
Definition: csharp_helpers.cc:356
google::protobuf::io::Printer
Definition: printer.h:181
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::FileDescriptor::name
const std::string & name() const
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
csharp_helpers.h
csharp_message.h
google::protobuf::compiler::csharp::ReflectionClassGenerator::ReflectionClassGenerator
ReflectionClassGenerator(const FileDescriptor *file, const Options *options)
Definition: csharp_reflection_class.cc:54
csharp_field_base.h
google::protobuf::compiler::csharp::GetClassName
std::string GetClassName(const Descriptor *descriptor)
Definition: csharp_helpers.cc:333
csharp_options.h
google::protobuf::compiler::csharp::SourceGeneratorBase::class_access_level
std::string class_access_level()
Definition: csharp_source_generator_base.cc:61
google::protobuf::compiler::csharp::FileDescriptorToBase64
std::string FileDescriptorToBase64(const FileDescriptor *descriptor)
Definition: csharp_helpers.cc:471
google::protobuf::FileDescriptor::message_type
const Descriptor * message_type(int index) const
google::protobuf::compiler::csharp::EnumGenerator
Definition: csharp_enum.h:46
google::protobuf::compiler::csharp::IsMapEntryMessage
bool IsMapEntryMessage(const Descriptor *descriptor)
Definition: csharp_helpers.h:121
google::protobuf::compiler::csharp::ReflectionClassGenerator::WriteDescriptor
void WriteDescriptor(io::Printer *printer)
Definition: csharp_reflection_class.cc:156
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: src/google/protobuf/descriptor.cc:7271
google::protobuf::EnumDescriptor::options
const EnumOptions & options() const
google::protobuf::FileDescriptor::extension
const FieldDescriptor * extension(int index) const
csharp_names.h
google::protobuf::compiler::csharp::SourceGeneratorBase
Definition: csharp_source_generator_base.h:46
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
descriptor.h
google::protobuf::compiler::csharp::ReflectionClassGenerator::file_
const FileDescriptor * file_
Definition: csharp_reflection_class.h:57
google::protobuf::FileDescriptor
Definition: src/google/protobuf/descriptor.h:1320
google::protobuf::compiler::csharp::GetExtensionClassUnqualifiedName
std::string GetExtensionClassUnqualifiedName(const FileDescriptor *descriptor)
Definition: csharp_helpers.cc:136
google::protobuf::compiler::csharp::UnderscoresToCamelCase
std::string UnderscoresToCamelCase(const std::string &input, bool cap_next_letter, bool preserve_period)
Definition: csharp_helpers.cc:143
descriptor.pb.h
google::protobuf::compiler::csharp::CreateFieldGenerator
FieldGeneratorBase * CreateFieldGenerator(const FieldDescriptor *descriptor, int presenceIndex, const Options *options)
Definition: csharp_helpers.cc:479
google::protobuf::compiler::csharp::ReflectionClassGenerator::reflectionClassname_
std::string reflectionClassname_
Definition: csharp_reflection_class.h:60
google::protobuf::FileDescriptor::message_type_count
int message_type_count() const
file_
FileDescriptorProto * file_
Definition: annotation_test_util.cc:68
google::protobuf::io::Printer::Outdent
void Outdent()
Definition: printer.cc:187
compiler
Definition: plugin.pb.cc:22
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::FileDescriptor::extension_count
int extension_count() const
google::protobuf::FileDescriptor::dependency_count
int dependency_count() const
google::protobuf::compiler::csharp::GetReflectionClassName
std::string GetReflectionClassName(const FileDescriptor *descriptor)
Definition: csharp_helpers.cc:315
google::protobuf::JoinStrings
void JoinStrings(const std::vector< string > &components, const char *delim, string *result)
Definition: strutil.cc:308


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:49