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 <iostream> 32 33 #include <google/protobuf/compiler/objectivec/objectivec_extension.h> 34 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h> 35 #include <google/protobuf/descriptor.pb.h> 36 #include <google/protobuf/stubs/strutil.h> 37 #include <google/protobuf/io/printer.h> 38 39 namespace google { 40 namespace protobuf { 41 namespace compiler { 42 namespace objectivec { 43 44 ExtensionGenerator::ExtensionGenerator(const string& root_class_name, 45 const FieldDescriptor* descriptor) 46 : method_name_(ExtensionMethodName(descriptor)), 47 root_class_and_method_name_(root_class_name + "_" + method_name_), 48 descriptor_(descriptor) { 49 if (descriptor->is_map()) { 50 // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some 51 // error cases, so it seems to be ok to use as a back door for errors. 52 cerr << "error: Extension is a map<>!" 53 << " That used to be blocked by the compiler." << endl; 54 cerr.flush(); 55 abort(); 56 } 57 } 58 59 ExtensionGenerator::~ExtensionGenerator() {} 60 61 void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { 62 map<string, string> vars; 63 vars["method_name"] = method_name_; 64 SourceLocation location; 65 if (descriptor_->GetSourceLocation(&location)) { 66 vars["comments"] = BuildCommentsString(location); 67 } else { 68 vars["comments"] = ""; 69 } 70 printer->Print(vars, 71 "$comments$" 72 "+ (GPBExtensionDescriptor *)$method_name$;\n"); 73 } 74 75 void ExtensionGenerator::GenerateStaticVariablesInitialization( 76 io::Printer* printer) { 77 map<string, string> vars; 78 vars["root_class_and_method_name"] = root_class_and_method_name_; 79 vars["extended_type"] = ClassName(descriptor_->containing_type()); 80 vars["number"] = SimpleItoa(descriptor_->number()); 81 82 std::vector<string> options; 83 if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated"); 84 if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked"); 85 if (descriptor_->containing_type()->options().message_set_wire_format()) 86 options.push_back("GPBExtensionSetWireFormat"); 87 88 vars["options"] = BuildFlagsString(options); 89 90 ObjectiveCType objc_type = GetObjectiveCType(descriptor_); 91 string singular_type; 92 if (objc_type == OBJECTIVECTYPE_MESSAGE) { 93 vars["type"] = string("GPBStringifySymbol(") + 94 ClassName(descriptor_->message_type()) + ")"; 95 } else { 96 vars["type"] = "NULL"; 97 } 98 99 vars["default_name"] = GPBGenericValueFieldName(descriptor_); 100 if (descriptor_->is_repeated()) { 101 vars["default"] = "nil"; 102 } else { 103 vars["default"] = DefaultValue(descriptor_); 104 } 105 string type = GetCapitalizedType(descriptor_); 106 vars["extension_type"] = string("GPBDataType") + type; 107 108 if (objc_type == OBJECTIVECTYPE_ENUM) { 109 vars["enum_desc_func_name"] = 110 EnumName(descriptor_->enum_type()) + "_EnumDescriptor"; 111 } else { 112 vars["enum_desc_func_name"] = "NULL"; 113 } 114 115 printer->Print(vars, 116 "{\n" 117 " .defaultValue.$default_name$ = $default$,\n" 118 " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n" 119 " .extendedClass = GPBStringifySymbol($extended_type$),\n" 120 " .messageOrGroupClassName = $type$,\n" 121 " .enumDescriptorFunc = $enum_desc_func_name$,\n" 122 " .fieldNumber = $number$,\n" 123 " .dataType = $extension_type$,\n" 124 " .options = $options$,\n" 125 "},\n"); 126 } 127 128 void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) { 129 printer->Print( 130 "[registry addExtension:$root_class_and_method_name$];\n", 131 "root_class_and_method_name", root_class_and_method_name_); 132 } 133 } // namespace objectivec 134 } // namespace compiler 135 } // namespace protobuf 136 } // namespace google 137