• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/java/java_extension.h>
36 #include <google/protobuf/compiler/java/java_helpers.h>
37 #include <google/protobuf/stubs/strutil.h>
38 #include <google/protobuf/io/printer.h>
39 
40 namespace google {
41 namespace protobuf {
42 namespace compiler {
43 namespace java {
44 
45 namespace {
46 
TypeName(FieldDescriptor::Type field_type)47 const char* TypeName(FieldDescriptor::Type field_type) {
48   switch (field_type) {
49     case FieldDescriptor::TYPE_INT32   : return "INT32";
50     case FieldDescriptor::TYPE_UINT32  : return "UINT32";
51     case FieldDescriptor::TYPE_SINT32  : return "SINT32";
52     case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
53     case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
54     case FieldDescriptor::TYPE_INT64   : return "INT64";
55     case FieldDescriptor::TYPE_UINT64  : return "UINT64";
56     case FieldDescriptor::TYPE_SINT64  : return "SINT64";
57     case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
58     case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
59     case FieldDescriptor::TYPE_FLOAT   : return "FLOAT";
60     case FieldDescriptor::TYPE_DOUBLE  : return "DOUBLE";
61     case FieldDescriptor::TYPE_BOOL    : return "BOOL";
62     case FieldDescriptor::TYPE_STRING  : return "STRING";
63     case FieldDescriptor::TYPE_BYTES   : return "BYTES";
64     case FieldDescriptor::TYPE_ENUM    : return "ENUM";
65     case FieldDescriptor::TYPE_GROUP   : return "GROUP";
66     case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
67 
68     // No default because we want the compiler to complain if any new
69     // types are added.
70   }
71 
72   GOOGLE_LOG(FATAL) << "Can't get here.";
73   return NULL;
74 }
75 
76 }
77 
ExtensionGenerator(const FieldDescriptor * descriptor)78 ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
79   : descriptor_(descriptor) {
80   if (descriptor_->extension_scope() != NULL) {
81     scope_ = ClassName(descriptor_->extension_scope());
82   } else {
83     scope_ = ClassName(descriptor_->file());
84   }
85 }
86 
~ExtensionGenerator()87 ExtensionGenerator::~ExtensionGenerator() {}
88 
Generate(io::Printer * printer)89 void ExtensionGenerator::Generate(io::Printer* printer) {
90   map<string, string> vars;
91   vars["name"] = UnderscoresToCamelCase(descriptor_);
92   vars["containing_type"] = ClassName(descriptor_->containing_type());
93   vars["number"] = SimpleItoa(descriptor_->number());
94   vars["constant_name"] = FieldConstantName(descriptor_);
95   vars["lite"] = HasDescriptorMethods(descriptor_->file()) ? "" : "Lite";
96 
97   JavaType java_type = GetJavaType(descriptor_);
98   string singular_type;
99   switch (java_type) {
100     case JAVATYPE_MESSAGE:
101       vars["type"] = ClassName(descriptor_->message_type());
102       break;
103     case JAVATYPE_ENUM:
104       vars["type"] = ClassName(descriptor_->enum_type());
105       break;
106     default:
107       vars["type"] = BoxedPrimitiveTypeName(java_type);
108       break;
109   }
110 
111   printer->Print(vars,
112     "public static final int $constant_name$ = $number$;\n");
113   if (descriptor_->is_repeated()) {
114     printer->Print(vars,
115       "public static final\n"
116       "  com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
117       "    $containing_type$,\n"
118       "    java.util.List<$type$>> $name$ =\n"
119       "      com.google.protobuf.GeneratedMessage$lite$\n"
120       "        .newGeneratedExtension();\n");
121   } else {
122     printer->Print(vars,
123       "public static final\n"
124       "  com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
125       "    $containing_type$,\n"
126       "    $type$> $name$ =\n"
127       "      com.google.protobuf.GeneratedMessage$lite$\n"
128       "        .newGeneratedExtension();\n");
129   }
130 }
131 
GenerateInitializationCode(io::Printer * printer)132 void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) {
133   map<string, string> vars;
134   vars["name"] = UnderscoresToCamelCase(descriptor_);
135   vars["scope"] = scope_;
136   vars["index"] = SimpleItoa(descriptor_->index());
137   vars["extendee"] = ClassName(descriptor_->containing_type());
138   vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_);
139   vars["number"] = SimpleItoa(descriptor_->number());
140   vars["type_constant"] = TypeName(GetType(descriptor_));
141   vars["packed"] = descriptor_->options().packed() ? "true" : "false";
142   vars["enum_map"] = "null";
143   vars["prototype"] = "null";
144 
145   JavaType java_type = GetJavaType(descriptor_);
146   string singular_type;
147   switch (java_type) {
148     case JAVATYPE_MESSAGE:
149       vars["type"] = ClassName(descriptor_->message_type());
150       vars["prototype"] = ClassName(descriptor_->message_type()) +
151                           ".getDefaultInstance()";
152       break;
153     case JAVATYPE_ENUM:
154       vars["type"] = ClassName(descriptor_->enum_type());
155       vars["enum_map"] = ClassName(descriptor_->enum_type()) +
156                          ".internalGetValueMap()";
157       break;
158     default:
159       vars["type"] = BoxedPrimitiveTypeName(java_type);
160       break;
161   }
162 
163   if (HasDescriptorMethods(descriptor_->file())) {
164     printer->Print(vars,
165       "$scope$.$name$.internalInit(\n"
166       "    $scope$.getDescriptor().getExtensions().get($index$),\n"
167       "    $type$.class);\n");
168   } else {
169     if (descriptor_->is_repeated()) {
170       printer->Print(vars,
171         "$scope$.$name$.internalInitRepeated(\n"
172         "    $extendee$.getDefaultInstance(),\n"
173         "    $prototype$,\n"
174         "    $enum_map$,\n"
175         "    $number$,\n"
176         "    com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
177         "    $packed$);\n");
178     } else {
179       printer->Print(vars,
180         "$scope$.$name$.internalInitSingular(\n"
181         "    $extendee$.getDefaultInstance(),\n"
182         "    $default$,\n"
183         "    $prototype$,\n"
184         "    $enum_map$,\n"
185         "    $number$,\n"
186         "    com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
187     }
188   }
189 }
190 
GenerateRegistrationCode(io::Printer * printer)191 void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) {
192   printer->Print(
193     "registry.add($scope$.$name$);\n",
194     "scope", scope_,
195     "name", UnderscoresToCamelCase(descriptor_));
196 }
197 
198 }  // namespace java
199 }  // namespace compiler
200 }  // namespace protobuf
201 }  // namespace google
202