LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/csharp - csharp_umbrella_class.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 125 0.0 %
Date: 2015-10-10 Functions: 0 7 0.0 %

          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             : #include <google/protobuf/stubs/strutil.h>
      40             : 
      41             : 
      42             : #include <google/protobuf/compiler/csharp/csharp_enum.h>
      43             : #include <google/protobuf/compiler/csharp/csharp_helpers.h>
      44             : #include <google/protobuf/compiler/csharp/csharp_message.h>
      45             : #include <google/protobuf/compiler/csharp/csharp_names.h>
      46             : #include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>
      47             : 
      48             : namespace google {
      49             : namespace protobuf {
      50             : namespace compiler {
      51             : namespace csharp {
      52             : 
      53           0 : UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file)
      54             :     : SourceGeneratorBase(file),
      55           0 :       file_(file) {
      56           0 :   namespace_ = GetFileNamespace(file);
      57           0 :   umbrellaClassname_ = GetUmbrellaClassUnqualifiedName(file);
      58           0 :   umbrellaNamespace_ = GetUmbrellaClassNestedNamespace(file);
      59           0 : }
      60             : 
      61           0 : UmbrellaClassGenerator::~UmbrellaClassGenerator() {
      62           0 : }
      63             : 
      64           0 : void UmbrellaClassGenerator::Generate(io::Printer* printer) {
      65           0 :   WriteIntroduction(printer);
      66             : 
      67           0 :   WriteDescriptor(printer);
      68             :   // Close the class declaration.
      69           0 :   printer->Outdent();
      70           0 :   printer->Print("}\n");
      71             : 
      72             :   // Close the namespace around the umbrella class if defined
      73           0 :   if (!umbrellaNamespace_.empty()) {
      74           0 :     printer->Outdent();
      75           0 :     printer->Print("}\n");
      76             :   }
      77             : 
      78             :   // write children: Enums
      79           0 :   if (file_->enum_type_count() > 0) {
      80           0 :     printer->Print("#region Enums\n");
      81           0 :     for (int i = 0; i < file_->enum_type_count(); i++) {
      82           0 :       EnumGenerator enumGenerator(file_->enum_type(i));
      83           0 :       enumGenerator.Generate(printer);
      84           0 :     }
      85           0 :     printer->Print("#endregion\n");
      86           0 :     printer->Print("\n");
      87             :   }
      88             : 
      89             :   // write children: Messages
      90           0 :   if (file_->message_type_count() > 0) {
      91           0 :     printer->Print("#region Messages\n");
      92           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
      93           0 :       MessageGenerator messageGenerator(file_->message_type(i));
      94           0 :       messageGenerator.Generate(printer);
      95           0 :     }
      96           0 :     printer->Print("#endregion\n");
      97           0 :     printer->Print("\n");
      98             :   }
      99             : 
     100             :   // TODO(jtattermusch): add insertion point for services.
     101             : 
     102           0 :   if (!namespace_.empty()) {
     103           0 :     printer->Outdent();
     104           0 :     printer->Print("}\n");
     105             :   }
     106           0 :   printer->Print("\n");
     107           0 :   printer->Print("#endregion Designer generated code\n");
     108           0 : }
     109             : 
     110           0 : void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
     111             :   printer->Print(
     112             :     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
     113             :     "// source: $file_name$\n"
     114             :     "#pragma warning disable 1591, 0612, 3021\n"
     115             :     "#region Designer generated code\n"
     116             :     "\n"
     117             :     "using pb = global::Google.Protobuf;\n"
     118             :     "using pbc = global::Google.Protobuf.Collections;\n"
     119             :     "using pbr = global::Google.Protobuf.Reflection;\n"
     120             :     "using scg = global::System.Collections.Generic;\n",
     121           0 :     "file_name", file_->name());
     122             : 
     123           0 :   if (!namespace_.empty()) {
     124           0 :     printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
     125           0 :     printer->Indent();
     126           0 :     printer->Print("\n");
     127             :   }
     128             : 
     129             :   // Add the namespace around the umbrella class if defined
     130           0 :   if (!umbrellaNamespace_.empty()) {
     131             :     printer->Print("namespace $umbrella_namespace$ {\n",
     132           0 :                    "umbrella_namespace", umbrellaNamespace_);
     133           0 :     printer->Indent();
     134           0 :     printer->Print("\n");
     135             :   }
     136             : 
     137             :   printer->Print(
     138           0 :     "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
     139           0 :   WriteGeneratedCodeAttributes(printer);
     140             :   printer->Print(
     141             :     "$access_level$ static partial class $umbrella_class_name$ {\n"
     142             :     "\n",
     143             :     "access_level", class_access_level(),
     144           0 :     "umbrella_class_name", umbrellaClassname_);
     145           0 :   printer->Indent();
     146           0 : }
     147             : 
     148           0 : void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
     149             :   printer->Print(
     150             :     "#region Descriptor\n"
     151             :     "public static pbr::FileDescriptor Descriptor {\n"
     152             :     "  get { return descriptor; }\n"
     153             :     "}\n"
     154             :     "private static pbr::FileDescriptor descriptor;\n"
     155             :     "\n"
     156             :     "static $umbrella_class_name$() {\n",
     157           0 :     "umbrella_class_name", umbrellaClassname_);
     158           0 :   printer->Indent();
     159             :   printer->Print(
     160           0 :     "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
     161           0 :   printer->Indent();
     162           0 :   printer->Indent();
     163           0 :   printer->Print("string.Concat(\n");
     164           0 :   printer->Indent();
     165             : 
     166             :   // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
     167           0 :   std::string base64 = FileDescriptorToBase64(file_);
     168           0 :   while (base64.size() > 60) {
     169           0 :     printer->Print("\"$base64$\", \n", "base64", base64.substr(0, 60));
     170           0 :     base64 = base64.substr(60);
     171             :   }
     172           0 :   printer->Print("\"$base64$\"));\n", "base64", base64);
     173           0 :   printer->Outdent();
     174           0 :   printer->Outdent();
     175           0 :   printer->Outdent();
     176             : 
     177             :   // -----------------------------------------------------------------
     178             :   // Invoke InternalBuildGeneratedFileFrom() to build the file.
     179             :   printer->Print(
     180           0 :       "descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
     181           0 :   printer->Print("    new pbr::FileDescriptor[] { ");
     182           0 :   for (int i = 0; i < file_->dependency_count(); i++) {
     183             :     // descriptor.proto is special: we don't allow access to the generated code, but there's
     184             :     // a separately-exposed property to get at the file descriptor, specifically to allow this
     185             :     // kind of dependency.
     186           0 :     if (IsDescriptorProto(file_->dependency(i))) {
     187           0 :       printer->Print("pbr::FileDescriptor.DescriptorProtoFileDescriptor, ");
     188             :     } else {
     189             :       printer->Print(
     190             :       "$full_umbrella_class_name$.Descriptor, ",
     191             :       "full_umbrella_class_name",
     192           0 :       GetUmbrellaClassName(file_->dependency(i)));
     193             :     }
     194             :   }
     195             :   printer->Print("},\n"
     196           0 :       "    new pbr::GeneratedCodeInfo(");
     197             :   // Specify all the generated code information, recursively.
     198           0 :   if (file_->enum_type_count() > 0) {
     199           0 :       printer->Print("new[] {");
     200           0 :       for (int i = 0; i < file_->enum_type_count(); i++) {
     201           0 :           printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i)));
     202             :       }
     203           0 :       printer->Print("}, ");
     204             :   }
     205             :   else {
     206           0 :       printer->Print("null, ");
     207             :   }
     208           0 :   if (file_->message_type_count() > 0) {
     209           0 :       printer->Print("new pbr::GeneratedCodeInfo[] {\n");
     210           0 :       printer->Indent();
     211           0 :       printer->Indent();
     212           0 :       printer->Indent();
     213           0 :       for (int i = 0; i < file_->message_type_count(); i++) {
     214           0 :           WriteGeneratedCodeInfo(file_->message_type(i), printer, i == file_->message_type_count() - 1);
     215             :       }
     216           0 :       printer->Outdent();
     217           0 :       printer->Print("\n}));\n");
     218           0 :       printer->Outdent();
     219           0 :       printer->Outdent();
     220             :   }
     221             :   else {
     222           0 :       printer->Print("null));\n");
     223             :   }
     224             : 
     225           0 :   printer->Outdent();
     226           0 :   printer->Print("}\n");
     227           0 :   printer->Print("#endregion\n\n");
     228           0 : }
     229             : 
     230             : // Write out the generated code for a particular message. This consists of the CLR type, property names
     231             : // corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part
     232             : // can be specified as null if it would be empty, to make the generated code somewhat simpler to read.
     233             : // We write a line break at the end of each generated code info, so that in the final file we'll see all
     234             : // the types, pre-ordered depth first, one per line. The indentation will be slightly unusual,
     235             : // in that it will look like a single array when it's actually constructing a tree, but it'll be easy to
     236             : // read even with multiple levels of nesting.
     237             : // The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate
     238             : // context. It governs whether or not a trailing comma and newline is written after the constructor, effectively
     239             : // just controlling the formatting in the generated code.
     240           0 : void UmbrellaClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last) {
     241           0 :   if (IsMapEntryMessage(descriptor)) {
     242           0 :     printer->Print("null, ");
     243           0 :     return;
     244             :   }
     245             :   // Generated message type
     246           0 :   printer->Print("new pbr::GeneratedCodeInfo(typeof($type_name$), ", "type_name", GetClassName(descriptor));
     247             :   
     248             :   // Fields
     249           0 :   if (descriptor->field_count() > 0) {
     250             :       std::vector<std::string> fields;
     251           0 :       for (int i = 0; i < descriptor->field_count(); i++) {
     252           0 :           fields.push_back(GetPropertyName(descriptor->field(i)));
     253             :       }
     254           0 :       printer->Print("new[]{ \"$fields$\" }, ", "fields", JoinStrings(fields, "\", \""));
     255             :   }
     256             :   else {
     257           0 :       printer->Print("null, ");
     258             :   }
     259             : 
     260             :   // Oneofs
     261           0 :   if (descriptor->oneof_decl_count() > 0) {
     262             :       std::vector<std::string> oneofs;
     263           0 :       for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
     264           0 :           oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
     265             :       }
     266           0 :       printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", JoinStrings(oneofs, "\", \""));
     267             :   }
     268             :   else {
     269           0 :       printer->Print("null, ");
     270             :   }
     271             : 
     272             :   // Nested enums
     273           0 :   if (descriptor->enum_type_count() > 0) {
     274             :       std::vector<std::string> enums;
     275           0 :       for (int i = 0; i < descriptor->enum_type_count(); i++) {
     276           0 :           enums.push_back(GetClassName(descriptor->enum_type(i)));
     277             :       }
     278           0 :       printer->Print("new[]{ typeof($enums$) }, ", "enums", JoinStrings(enums, "), typeof("));
     279             :   }
     280             :   else {
     281           0 :       printer->Print("null, ");
     282             :   }
     283             : 
     284             :   // Nested types
     285           0 :   if (descriptor->nested_type_count() > 0) {
     286             :       // Need to specify array type explicitly here, as all elements may be null. 
     287           0 :       printer->Print("new pbr::GeneratedCodeInfo[] { ");
     288           0 :       for (int i = 0; i < descriptor->nested_type_count(); i++) {
     289           0 :           WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
     290             :       }
     291           0 :       printer->Print("}");
     292             :   }
     293             :   else {
     294           0 :       printer->Print("null");
     295             :   }
     296           0 :   printer->Print(last ? ")" : "),\n");
     297             : }
     298             : 
     299             : }  // namespace csharp
     300             : }  // namespace compiler
     301             : }  // namespace protobuf
     302             : }  // namespace google

Generated by: LCOV version 1.10