blob: 9b147c7766eb8a02682760b9950b7b96bc2f1c4b [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
temporal40ee5512008-07-10 02:12:20 +00003// http://code.google.com/p/protobuf/
4//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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
40namespace google {
41namespace protobuf {
42namespace compiler {
43namespace java {
44
kenton@google.com80b1d622009-07-29 01:13:20 +000045namespace {
46
47const 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
temporal40ee5512008-07-10 02:12:20 +000078ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
kenton@google.com24bf56f2008-09-24 20:31:01 +000079 : descriptor_(descriptor) {
80 if (descriptor_->extension_scope() != NULL) {
81 scope_ = ClassName(descriptor_->extension_scope());
82 } else {
83 scope_ = ClassName(descriptor_->file());
84 }
85}
temporal40ee5512008-07-10 02:12:20 +000086
87ExtensionGenerator::~ExtensionGenerator() {}
88
liujisi@google.com33165fe2010-11-02 13:14:58 +000089// Initializes the vars referenced in the generated code templates.
90void InitTemplateVars(const FieldDescriptor* descriptor,
91 const string& scope,
92 map<string, string>* vars_pointer) {
93 map<string, string> &vars = *vars_pointer;
94 vars["scope"] = scope;
95 vars["name"] = UnderscoresToCamelCase(descriptor);
96 vars["containing_type"] = ClassName(descriptor->containing_type());
97 vars["number"] = SimpleItoa(descriptor->number());
98 vars["constant_name"] = FieldConstantName(descriptor);
99 vars["index"] = SimpleItoa(descriptor->index());
100 vars["default"] =
101 descriptor->is_repeated() ? "" : DefaultValue(descriptor);
102 vars["type_constant"] = TypeName(GetType(descriptor));
103 vars["packed"] = descriptor->options().packed() ? "true" : "false";
kenton@google.com80b1d622009-07-29 01:13:20 +0000104 vars["enum_map"] = "null";
105 vars["prototype"] = "null";
temporal40ee5512008-07-10 02:12:20 +0000106
liujisi@google.com33165fe2010-11-02 13:14:58 +0000107 JavaType java_type = GetJavaType(descriptor);
temporal40ee5512008-07-10 02:12:20 +0000108 string singular_type;
109 switch (java_type) {
110 case JAVATYPE_MESSAGE:
liujisi@google.com33165fe2010-11-02 13:14:58 +0000111 singular_type = ClassName(descriptor->message_type());
112 vars["prototype"] = singular_type + ".getDefaultInstance()";
temporal40ee5512008-07-10 02:12:20 +0000113 break;
114 case JAVATYPE_ENUM:
liujisi@google.com33165fe2010-11-02 13:14:58 +0000115 singular_type = ClassName(descriptor->enum_type());
116 vars["enum_map"] = singular_type + ".internalGetValueMap()";
temporal40ee5512008-07-10 02:12:20 +0000117 break;
118 default:
liujisi@google.com33165fe2010-11-02 13:14:58 +0000119 singular_type = BoxedPrimitiveTypeName(java_type);
temporal40ee5512008-07-10 02:12:20 +0000120 break;
121 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000122 vars["type"] = descriptor->is_repeated() ?
123 "java.util.List<" + singular_type + ">" : singular_type;
124 vars["singular_type"] = singular_type;
125}
126
127void ExtensionGenerator::Generate(io::Printer* printer) {
128 map<string, string> vars;
129 InitTemplateVars(descriptor_, scope_, &vars);
130 printer->Print(vars,
131 "public static final int $constant_name$ = $number$;\n");
temporal40ee5512008-07-10 02:12:20 +0000132
kenton@google.com80b1d622009-07-29 01:13:20 +0000133 if (HasDescriptorMethods(descriptor_->file())) {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000134 // Non-lite extensions
135 if (descriptor_->extension_scope() == NULL) {
136 // Non-nested
137 printer->Print(
138 vars,
139 "public static final\n"
140 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
141 " $containing_type$,\n"
142 " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
143 " .newFileScopedGeneratedExtension(\n"
144 " $singular_type$.class,\n"
145 " $prototype$);\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000146 } else {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000147 // Nested
148 printer->Print(
149 vars,
150 "public static final\n"
151 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
152 " $containing_type$,\n"
153 " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
154 " .newMessageScopedGeneratedExtension(\n"
155 " $scope$.getDefaultInstance(),\n"
156 " $index$,\n"
157 " $singular_type$.class,\n"
158 " $prototype$);\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000159 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000160 } else {
161 // Lite extensions
162 if (descriptor_->is_repeated()) {
163 printer->Print(
164 vars,
165 "public static final\n"
166 " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
167 " $containing_type$,\n"
168 " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
169 " .newRepeatedGeneratedExtension(\n"
170 " $containing_type$.getDefaultInstance(),\n"
171 " $prototype$,\n"
172 " $enum_map$,\n"
173 " $number$,\n"
174 " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
175 " $packed$);\n");
176 } else {
177 printer->Print(
178 vars,
179 "public static final\n"
180 " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
181 " $containing_type$,\n"
182 " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
183 " .newSingularGeneratedExtension(\n"
184 " $containing_type$.getDefaultInstance(),\n"
185 " $default$,\n"
186 " $prototype$,\n"
187 " $enum_map$,\n"
188 " $number$,\n"
189 " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
190 }
191 }
192}
193
194void ExtensionGenerator::GenerateNonNestedInitializationCode(
195 io::Printer* printer) {
196 if (descriptor_->extension_scope() == NULL &&
197 HasDescriptorMethods(descriptor_->file())) {
198 // Only applies to non-nested, non-lite extensions.
199 printer->Print(
200 "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
201 "name", UnderscoresToCamelCase(descriptor_),
202 "index", SimpleItoa(descriptor_->index()));
temporal40ee5512008-07-10 02:12:20 +0000203 }
204}
205
kenton@google.com24bf56f2008-09-24 20:31:01 +0000206void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) {
207 printer->Print(
208 "registry.add($scope$.$name$);\n",
209 "scope", scope_,
210 "name", UnderscoresToCamelCase(descriptor_));
211}
212
temporal40ee5512008-07-10 02:12:20 +0000213} // namespace java
214} // namespace compiler
215} // namespace protobuf
temporal40ee5512008-07-10 02:12:20 +0000216} // namespace google