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 <map>
32 #include <string>
33
34 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
35 #include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h>
36 #include <google/protobuf/io/printer.h>
37 #include <google/protobuf/stubs/strutil.h>
38 #include <google/protobuf/wire_format.h>
39 #include <google/protobuf/wire_format_lite.h>
40
41 namespace google {
42 namespace protobuf {
43 namespace compiler {
44 namespace objectivec {
45
46 using internal::WireFormat;
47 using internal::WireFormatLite;
48
49 namespace {
50
PrimitiveTypeName(const FieldDescriptor * descriptor)51 const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
52 ObjectiveCType type = GetObjectiveCType(descriptor);
53 switch (type) {
54 case OBJECTIVECTYPE_INT32:
55 return "int32_t";
56 case OBJECTIVECTYPE_UINT32:
57 return "uint32_t";
58 case OBJECTIVECTYPE_INT64:
59 return "int64_t";
60 case OBJECTIVECTYPE_UINT64:
61 return "uint64_t";
62 case OBJECTIVECTYPE_FLOAT:
63 return "float";
64 case OBJECTIVECTYPE_DOUBLE:
65 return "double";
66 case OBJECTIVECTYPE_BOOLEAN:
67 return "BOOL";
68 case OBJECTIVECTYPE_STRING:
69 return "NSString";
70 case OBJECTIVECTYPE_DATA:
71 return "NSData";
72 case OBJECTIVECTYPE_ENUM:
73 return "int32_t";
74 case OBJECTIVECTYPE_MESSAGE:
75 return NULL; // Messages go through objectivec_message_field.cc|h.
76 }
77
78 // Some compilers report reaching end of function even though all cases of
79 // the enum are handed in the switch.
80 GOOGLE_LOG(FATAL) << "Can't get here.";
81 return NULL;
82 }
83
PrimitiveArrayTypeName(const FieldDescriptor * descriptor)84 const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
85 ObjectiveCType type = GetObjectiveCType(descriptor);
86 switch (type) {
87 case OBJECTIVECTYPE_INT32:
88 return "Int32";
89 case OBJECTIVECTYPE_UINT32:
90 return "UInt32";
91 case OBJECTIVECTYPE_INT64:
92 return "Int64";
93 case OBJECTIVECTYPE_UINT64:
94 return "UInt64";
95 case OBJECTIVECTYPE_FLOAT:
96 return "Float";
97 case OBJECTIVECTYPE_DOUBLE:
98 return "Double";
99 case OBJECTIVECTYPE_BOOLEAN:
100 return "Bool";
101 case OBJECTIVECTYPE_STRING:
102 return ""; // Want NSArray
103 case OBJECTIVECTYPE_DATA:
104 return ""; // Want NSArray
105 case OBJECTIVECTYPE_ENUM:
106 return "Enum";
107 case OBJECTIVECTYPE_MESSAGE:
108 // Want NSArray (but goes through objectivec_message_field.cc|h).
109 return "";
110 }
111
112 // Some compilers report reaching end of function even though all cases of
113 // the enum are handed in the switch.
114 GOOGLE_LOG(FATAL) << "Can't get here.";
115 return NULL;
116 }
117
SetPrimitiveVariables(const FieldDescriptor * descriptor,std::map<string,string> * variables)118 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
119 std::map<string, string>* variables) {
120 std::string primitive_name = PrimitiveTypeName(descriptor);
121 (*variables)["type"] = primitive_name;
122 (*variables)["storage_type"] = primitive_name;
123 }
124
125 } // namespace
126
PrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Options & options)127 PrimitiveFieldGenerator::PrimitiveFieldGenerator(
128 const FieldDescriptor* descriptor, const Options& options)
129 : SingleFieldGenerator(descriptor, options) {
130 SetPrimitiveVariables(descriptor, &variables_);
131 }
132
~PrimitiveFieldGenerator()133 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
134
GenerateFieldStorageDeclaration(io::Printer * printer) const135 void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
136 io::Printer* printer) const {
137 if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
138 // Nothing, BOOLs are stored in the has bits.
139 } else {
140 SingleFieldGenerator::GenerateFieldStorageDeclaration(printer);
141 }
142 }
143
ExtraRuntimeHasBitsNeeded(void) const144 int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
145 if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
146 // Reserve a bit for the storage of the boolean.
147 return 1;
148 }
149 return 0;
150 }
151
SetExtraRuntimeHasBitsBase(int has_base)152 void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
153 if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
154 // Set into the offset the has bit to use for the actual value.
155 variables_["storage_offset_value"] = StrCat(has_base);
156 variables_["storage_offset_comment"] =
157 " // Stored in _has_storage_ to save space.";
158 }
159 }
160
PrimitiveObjFieldGenerator(const FieldDescriptor * descriptor,const Options & options)161 PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
162 const FieldDescriptor* descriptor, const Options& options)
163 : ObjCObjFieldGenerator(descriptor, options) {
164 SetPrimitiveVariables(descriptor, &variables_);
165 variables_["property_storage_attribute"] = "copy";
166 }
167
~PrimitiveObjFieldGenerator()168 PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
169
RepeatedPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Options & options)170 RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
171 const FieldDescriptor* descriptor, const Options& options)
172 : RepeatedFieldGenerator(descriptor, options) {
173 SetPrimitiveVariables(descriptor, &variables_);
174
175 string base_name = PrimitiveArrayTypeName(descriptor);
176 if (base_name.length()) {
177 variables_["array_storage_type"] = "GPB" + base_name + "Array";
178 } else {
179 variables_["array_storage_type"] = "NSMutableArray";
180 variables_["array_property_type"] =
181 "NSMutableArray<" + variables_["storage_type"] + "*>";
182 }
183 }
184
~RepeatedPrimitiveFieldGenerator()185 RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
186
187 } // namespace objectivec
188 } // namespace compiler
189 } // namespace protobuf
190 } // namespace google
191