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: bduff@google.com (Brian Duff) 32 33#include <google/protobuf/compiler/javanano/javanano_extension.h> 34#include <google/protobuf/compiler/javanano/javanano_helpers.h> 35#include <google/protobuf/io/printer.h> 36#include <google/protobuf/stubs/strutil.h> 37#include <google/protobuf/wire_format.h> 38 39namespace google { 40namespace protobuf { 41namespace compiler { 42namespace javanano { 43 44using internal::WireFormat; 45using internal::WireFormatLite; 46 47namespace { 48 49const char* GetTypeConstantName(const FieldDescriptor::Type type) { 50 switch (type) { 51 case FieldDescriptor::TYPE_INT32 : return "TYPE_INT32" ; 52 case FieldDescriptor::TYPE_UINT32 : return "TYPE_UINT32" ; 53 case FieldDescriptor::TYPE_SINT32 : return "TYPE_SINT32" ; 54 case FieldDescriptor::TYPE_FIXED32 : return "TYPE_FIXED32" ; 55 case FieldDescriptor::TYPE_SFIXED32: return "TYPE_SFIXED32"; 56 case FieldDescriptor::TYPE_INT64 : return "TYPE_INT64" ; 57 case FieldDescriptor::TYPE_UINT64 : return "TYPE_UINT64" ; 58 case FieldDescriptor::TYPE_SINT64 : return "TYPE_SINT64" ; 59 case FieldDescriptor::TYPE_FIXED64 : return "TYPE_FIXED64" ; 60 case FieldDescriptor::TYPE_SFIXED64: return "TYPE_SFIXED64"; 61 case FieldDescriptor::TYPE_FLOAT : return "TYPE_FLOAT" ; 62 case FieldDescriptor::TYPE_DOUBLE : return "TYPE_DOUBLE" ; 63 case FieldDescriptor::TYPE_BOOL : return "TYPE_BOOL" ; 64 case FieldDescriptor::TYPE_STRING : return "TYPE_STRING" ; 65 case FieldDescriptor::TYPE_BYTES : return "TYPE_BYTES" ; 66 case FieldDescriptor::TYPE_ENUM : return "TYPE_ENUM" ; 67 case FieldDescriptor::TYPE_GROUP : return "TYPE_GROUP" ; 68 case FieldDescriptor::TYPE_MESSAGE : return "TYPE_MESSAGE" ; 69 70 // No default because we want the compiler to complain if any new 71 // types are added. 72 } 73 74 GOOGLE_LOG(FATAL) << "Can't get here."; 75 return NULL; 76} 77 78} // namespace 79 80void SetVariables(const FieldDescriptor* descriptor, const Params params, 81 map<string, string>* variables) { 82 (*variables)["extends"] = ClassName(params, descriptor->containing_type()); 83 (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); 84 bool repeated = descriptor->is_repeated(); 85 (*variables)["repeated"] = repeated ? "Repeated" : ""; 86 (*variables)["type"] = GetTypeConstantName(descriptor->type()); 87 JavaType java_type = GetJavaType(descriptor->type()); 88 string tag = SimpleItoa(WireFormat::MakeTag(descriptor)); 89 if (java_type == JAVATYPE_MESSAGE) { 90 (*variables)["ext_type"] = "MessageTyped"; 91 string message_type = ClassName(params, descriptor->message_type()); 92 if (repeated) { 93 message_type += "[]"; 94 } 95 (*variables)["class"] = message_type; 96 // For message typed extensions, tags_params contains a single tag 97 // for both singular and repeated cases. 98 (*variables)["tag_params"] = tag; 99 } else { 100 (*variables)["ext_type"] = "PrimitiveTyped"; 101 if (!repeated) { 102 (*variables)["class"] = BoxedPrimitiveTypeName(java_type); 103 (*variables)["tag_params"] = tag; 104 } else { 105 (*variables)["class"] = PrimitiveTypeName(java_type) + "[]"; 106 if (!descriptor->is_packable()) { 107 // Non-packable: nonPackedTag == tag, packedTag == 0 108 (*variables)["tag_params"] = tag + ", " + tag + ", 0"; 109 } else if (descriptor->options().packed()) { 110 // Packable and packed: tag == packedTag 111 string non_packed_tag = SimpleItoa(WireFormatLite::MakeTag( 112 descriptor->number(), 113 WireFormat::WireTypeForFieldType(descriptor->type()))); 114 (*variables)["tag_params"] = tag + ", " + non_packed_tag + ", " + tag; 115 } else { 116 // Packable and not packed: tag == nonPackedTag 117 string packed_tag = SimpleItoa(WireFormatLite::MakeTag( 118 descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); 119 (*variables)["tag_params"] = tag + ", " + tag + ", " + packed_tag; 120 } 121 } 122 } 123} 124 125ExtensionGenerator:: 126ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params) 127 : params_(params), descriptor_(descriptor) { 128 SetVariables(descriptor, params, &variables_); 129} 130 131ExtensionGenerator::~ExtensionGenerator() {} 132 133void ExtensionGenerator::Generate(io::Printer* printer) const { 134 printer->Print("\n"); 135 PrintFieldComment(printer, descriptor_); 136 printer->Print(variables_, 137 "public static final com.google.protobuf.nano.Extension<\n" 138 " $extends$,\n" 139 " $class$> $name$ =\n" 140 " com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n" 141 " com.google.protobuf.nano.Extension.$type$,\n" 142 " $class$.class,\n" 143 " $tag_params$);\n"); 144} 145 146} // namespace javanano 147} // namespace compiler 148} // namespace protobuf 149} // namespace google 150 151