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