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 40namespace google { 41namespace protobuf { 42namespace compiler { 43namespace java { 44 45namespace { 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 78ExtensionGenerator::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 87ExtensionGenerator::~ExtensionGenerator() {} 88 89void 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 132void 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 191void 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