• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ExtensionGenerator(const string & root_class_name,const FieldDescriptor * descriptor)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 
~ExtensionGenerator()59 ExtensionGenerator::~ExtensionGenerator() {}
60 
GenerateMembersHeader(io::Printer * printer)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 
GenerateStaticVariablesInitialization(io::Printer * printer)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 
GenerateRegistrationSource(io::Printer * printer)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