OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // http://code.google.com/p/protobuf/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
(...skipping 11 matching lines...) Expand all Loading... |
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | 30 |
31 // Author: kenton@google.com (Kenton Varda) | 31 // Author: kenton@google.com (Kenton Varda) |
32 // Based on original Protocol Buffers design by | 32 // Based on original Protocol Buffers design by |
33 // Sanjay Ghemawat, Jeff Dean, and others. | 33 // Sanjay Ghemawat, Jeff Dean, and others. |
34 | 34 |
35 #include <algorithm> | |
36 #include <google/protobuf/stubs/hash.h> | |
37 #include <limits> | 35 #include <limits> |
38 #include <vector> | 36 #include <vector> |
39 | 37 |
40 #include <google/protobuf/compiler/java/java_helpers.h> | 38 #include <google/protobuf/compiler/java/java_helpers.h> |
41 #include <google/protobuf/compiler/java/java_name_resolver.h> | |
42 #include <google/protobuf/descriptor.pb.h> | 39 #include <google/protobuf/descriptor.pb.h> |
43 #include <google/protobuf/wire_format.h> | |
44 #include <google/protobuf/stubs/strutil.h> | 40 #include <google/protobuf/stubs/strutil.h> |
45 #include <google/protobuf/stubs/substitute.h> | 41 #include <google/protobuf/stubs/substitute.h> |
46 | 42 |
47 namespace google { | 43 namespace google { |
48 namespace protobuf { | 44 namespace protobuf { |
49 namespace compiler { | 45 namespace compiler { |
50 namespace java { | 46 namespace java { |
51 | 47 |
52 using internal::WireFormat; | |
53 using internal::WireFormatLite; | |
54 | |
55 const char kThickSeparator[] = | 48 const char kThickSeparator[] = |
56 "// ===================================================================\n"; | 49 "// ===================================================================\n"; |
57 const char kThinSeparator[] = | 50 const char kThinSeparator[] = |
58 "// -------------------------------------------------------------------\n"; | 51 "// -------------------------------------------------------------------\n"; |
59 | 52 |
60 namespace { | 53 namespace { |
61 | 54 |
62 const char* kDefaultPackage = ""; | 55 const char* kDefaultPackage = ""; |
63 | 56 |
64 // Names that should be avoided as field names. | 57 const string& FieldName(const FieldDescriptor* field) { |
65 // Using them will cause the compiler to generate accessors whose names are | |
66 // colliding with methods defined in base classes. | |
67 const char* kForbiddenWordList[] = { | |
68 // message base class: | |
69 "cached_size", "serialized_size", | |
70 // java.lang.Object: | |
71 "class", | |
72 }; | |
73 | |
74 bool IsForbidden(const string& field_name) { | |
75 for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { | |
76 if (field_name == kForbiddenWordList[i]) { | |
77 return true; | |
78 } | |
79 } | |
80 return false; | |
81 } | |
82 | |
83 string FieldName(const FieldDescriptor* field) { | |
84 string field_name; | |
85 // Groups are hacky: The name of the field is just the lower-cased name | 58 // Groups are hacky: The name of the field is just the lower-cased name |
86 // of the group type. In Java, though, we would like to retain the original | 59 // of the group type. In Java, though, we would like to retain the original |
87 // capitalization of the type name. | 60 // capitalization of the type name. |
88 if (GetType(field) == FieldDescriptor::TYPE_GROUP) { | 61 if (GetType(field) == FieldDescriptor::TYPE_GROUP) { |
89 field_name = field->message_type()->name(); | 62 return field->message_type()->name(); |
90 } else { | 63 } else { |
91 field_name = field->name(); | 64 return field->name(); |
92 } | 65 } |
93 if (IsForbidden(field_name)) { | |
94 // Append a trailing "#" to indicate that the name should be decorated to | |
95 // avoid collision with other names. | |
96 field_name += "#"; | |
97 } | |
98 return field_name; | |
99 } | 66 } |
100 | 67 |
101 | 68 string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { |
102 } // namespace | |
103 | |
104 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { | |
105 string result; | 69 string result; |
106 // Note: I distrust ctype.h due to locales. | 70 // Note: I distrust ctype.h due to locales. |
107 for (int i = 0; i < input.size(); i++) { | 71 for (int i = 0; i < input.size(); i++) { |
108 if ('a' <= input[i] && input[i] <= 'z') { | 72 if ('a' <= input[i] && input[i] <= 'z') { |
109 if (cap_next_letter) { | 73 if (cap_next_letter) { |
110 result += input[i] + ('A' - 'a'); | 74 result += input[i] + ('A' - 'a'); |
111 } else { | 75 } else { |
112 result += input[i]; | 76 result += input[i]; |
113 } | 77 } |
114 cap_next_letter = false; | 78 cap_next_letter = false; |
115 } else if ('A' <= input[i] && input[i] <= 'Z') { | 79 } else if ('A' <= input[i] && input[i] <= 'Z') { |
116 if (i == 0 && !cap_next_letter) { | 80 if (i == 0 && !cap_next_letter) { |
117 // Force first letter to lower-case unless explicitly told to | 81 // Force first letter to lower-case unless explicitly told to |
118 // capitalize it. | 82 // capitalize it. |
119 result += input[i] + ('a' - 'A'); | 83 result += input[i] + ('a' - 'A'); |
120 } else { | 84 } else { |
121 // Capital letters after the first are left as-is. | 85 // Capital letters after the first are left as-is. |
122 result += input[i]; | 86 result += input[i]; |
123 } | 87 } |
124 cap_next_letter = false; | 88 cap_next_letter = false; |
125 } else if ('0' <= input[i] && input[i] <= '9') { | 89 } else if ('0' <= input[i] && input[i] <= '9') { |
126 result += input[i]; | 90 result += input[i]; |
127 cap_next_letter = true; | 91 cap_next_letter = true; |
128 } else { | 92 } else { |
129 cap_next_letter = true; | 93 cap_next_letter = true; |
130 } | 94 } |
131 } | 95 } |
132 // Add a trailing "_" if the name should be altered. | |
133 if (input[input.size() - 1] == '#') { | |
134 result += '_'; | |
135 } | |
136 return result; | 96 return result; |
137 } | 97 } |
138 | 98 |
| 99 } // namespace |
| 100 |
139 string UnderscoresToCamelCase(const FieldDescriptor* field) { | 101 string UnderscoresToCamelCase(const FieldDescriptor* field) { |
140 return UnderscoresToCamelCase(FieldName(field), false); | 102 return UnderscoresToCamelCaseImpl(FieldName(field), false); |
141 } | 103 } |
142 | 104 |
143 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { | 105 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { |
144 return UnderscoresToCamelCase(FieldName(field), true); | 106 return UnderscoresToCamelCaseImpl(FieldName(field), true); |
145 } | 107 } |
146 | 108 |
147 string UnderscoresToCamelCase(const MethodDescriptor* method) { | 109 string UnderscoresToCamelCase(const MethodDescriptor* method) { |
148 return UnderscoresToCamelCase(method->name(), false); | 110 return UnderscoresToCamelCaseImpl(method->name(), false); |
149 } | |
150 | |
151 string UniqueFileScopeIdentifier(const Descriptor* descriptor) { | |
152 return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); | |
153 } | 111 } |
154 | 112 |
155 string StripProto(const string& filename) { | 113 string StripProto(const string& filename) { |
156 if (HasSuffixString(filename, ".protodevel")) { | 114 if (HasSuffixString(filename, ".protodevel")) { |
157 return StripSuffixString(filename, ".protodevel"); | 115 return StripSuffixString(filename, ".protodevel"); |
158 } else { | 116 } else { |
159 return StripSuffixString(filename, ".proto"); | 117 return StripSuffixString(filename, ".proto"); |
160 } | 118 } |
161 } | 119 } |
162 | 120 |
163 string FileClassName(const FileDescriptor* file, bool immutable) { | 121 string FileClassName(const FileDescriptor* file) { |
164 ClassNameResolver name_resolver; | 122 if (file->options().has_java_outer_classname()) { |
165 return name_resolver.GetFileClassName(file, immutable); | 123 return file->options().java_outer_classname(); |
| 124 } else { |
| 125 string basename; |
| 126 string::size_type last_slash = file->name().find_last_of('/'); |
| 127 if (last_slash == string::npos) { |
| 128 basename = file->name(); |
| 129 } else { |
| 130 basename = file->name().substr(last_slash + 1); |
| 131 } |
| 132 return UnderscoresToCamelCaseImpl(StripProto(basename), true); |
| 133 } |
166 } | 134 } |
167 | 135 |
168 string FileJavaPackage(const FileDescriptor* file, bool immutable) { | 136 string FileJavaPackage(const FileDescriptor* file) { |
169 string result; | 137 string result; |
170 | 138 |
171 if (file->options().has_java_package()) { | 139 if (file->options().has_java_package()) { |
172 result = file->options().java_package(); | 140 result = file->options().java_package(); |
173 } else { | 141 } else { |
174 result = kDefaultPackage; | 142 result = kDefaultPackage; |
175 if (!file->package().empty()) { | 143 if (!file->package().empty()) { |
176 if (!result.empty()) result += '.'; | 144 if (!result.empty()) result += '.'; |
177 result += file->package(); | 145 result += file->package(); |
178 } | 146 } |
179 } | 147 } |
180 | 148 |
| 149 |
181 return result; | 150 return result; |
182 } | 151 } |
183 | 152 |
184 string JavaPackageToDir(string package_name) { | 153 string JavaPackageToDir(string package_name) { |
185 string package_dir = | 154 string package_dir = |
186 StringReplace(package_name, ".", "/", true); | 155 StringReplace(package_name, ".", "/", true); |
187 if (!package_dir.empty()) package_dir += "/"; | 156 if (!package_dir.empty()) package_dir += "/"; |
188 return package_dir; | 157 return package_dir; |
189 } | 158 } |
190 | 159 |
191 // TODO(xiaofeng): This function is only kept for it's publicly referenced. | 160 string ToJavaName(const string& full_name, const FileDescriptor* file) { |
192 // It should be removed after mutable API up-integration. | |
193 string ToJavaName(const string& full_name, | |
194 const FileDescriptor* file) { | |
195 string result; | 161 string result; |
196 if (file->options().java_multiple_files()) { | 162 if (file->options().java_multiple_files()) { |
197 result = FileJavaPackage(file); | 163 result = FileJavaPackage(file); |
198 } else { | 164 } else { |
199 result = ClassName(file); | 165 result = ClassName(file); |
200 } | 166 } |
201 if (!result.empty()) { | 167 if (!result.empty()) { |
202 result += '.'; | 168 result += '.'; |
203 } | 169 } |
204 if (file->package().empty()) { | 170 if (file->package().empty()) { |
205 result += full_name; | 171 result += full_name; |
206 } else { | 172 } else { |
207 // Strip the proto package from full_name since we've replaced it with | 173 // Strip the proto package from full_name since we've replaced it with |
208 // the Java package. | 174 // the Java package. |
209 result += full_name.substr(file->package().size() + 1); | 175 result += full_name.substr(file->package().size() + 1); |
210 } | 176 } |
211 return result; | 177 return result; |
212 } | 178 } |
213 | 179 |
214 string ClassName(const Descriptor* descriptor) { | 180 string ClassName(const Descriptor* descriptor) { |
215 ClassNameResolver name_resolver; | 181 return ToJavaName(descriptor->full_name(), descriptor->file()); |
216 return name_resolver.GetClassName(descriptor, true); | |
217 } | 182 } |
218 | 183 |
219 string ClassName(const EnumDescriptor* descriptor) { | 184 string ClassName(const EnumDescriptor* descriptor) { |
220 ClassNameResolver name_resolver; | 185 return ToJavaName(descriptor->full_name(), descriptor->file()); |
221 return name_resolver.GetClassName(descriptor, true); | |
222 } | 186 } |
223 | 187 |
224 string ClassName(const ServiceDescriptor* descriptor) { | 188 string ClassName(const ServiceDescriptor* descriptor) { |
225 ClassNameResolver name_resolver; | 189 return ToJavaName(descriptor->full_name(), descriptor->file()); |
226 return name_resolver.GetClassName(descriptor, true); | |
227 } | 190 } |
228 | 191 |
229 string ClassName(const FileDescriptor* descriptor) { | 192 string ClassName(const FileDescriptor* descriptor) { |
230 ClassNameResolver name_resolver; | 193 string result = FileJavaPackage(descriptor); |
231 return name_resolver.GetClassName(descriptor, true); | 194 if (!result.empty()) result += '.'; |
232 } | 195 result += FileClassName(descriptor); |
233 | 196 return result; |
234 string ExtraMessageInterfaces(const Descriptor* descriptor) { | |
235 string interfaces = "// @@protoc_insertion_point(message_implements:" | |
236 + descriptor->full_name() + ")"; | |
237 return interfaces; | |
238 } | |
239 | |
240 | |
241 string ExtraBuilderInterfaces(const Descriptor* descriptor) { | |
242 string interfaces = "// @@protoc_insertion_point(builder_implements:" | |
243 + descriptor->full_name() + ")"; | |
244 return interfaces; | |
245 } | |
246 | |
247 string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) { | |
248 string interfaces = "// @@protoc_insertion_point(interface_extends:" | |
249 + descriptor->full_name() + ")"; | |
250 return interfaces; | |
251 } | 197 } |
252 | 198 |
253 string FieldConstantName(const FieldDescriptor *field) { | 199 string FieldConstantName(const FieldDescriptor *field) { |
254 string name = field->name() + "_FIELD_NUMBER"; | 200 string name = field->name() + "_FIELD_NUMBER"; |
255 UpperString(&name); | 201 UpperString(&name); |
256 return name; | 202 return name; |
257 } | 203 } |
258 | 204 |
259 FieldDescriptor::Type GetType(const FieldDescriptor* field) { | 205 FieldDescriptor::Type GetType(const FieldDescriptor* field) { |
260 return field->type(); | 206 return field->type(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 return JAVATYPE_MESSAGE; | 245 return JAVATYPE_MESSAGE; |
300 | 246 |
301 // No default because we want the compiler to complain if any new | 247 // No default because we want the compiler to complain if any new |
302 // types are added. | 248 // types are added. |
303 } | 249 } |
304 | 250 |
305 GOOGLE_LOG(FATAL) << "Can't get here."; | 251 GOOGLE_LOG(FATAL) << "Can't get here."; |
306 return JAVATYPE_INT; | 252 return JAVATYPE_INT; |
307 } | 253 } |
308 | 254 |
309 const char* PrimitiveTypeName(JavaType type) { | |
310 switch (type) { | |
311 case JAVATYPE_INT : return "int"; | |
312 case JAVATYPE_LONG : return "long"; | |
313 case JAVATYPE_FLOAT : return "float"; | |
314 case JAVATYPE_DOUBLE : return "double"; | |
315 case JAVATYPE_BOOLEAN: return "boolean"; | |
316 case JAVATYPE_STRING : return "java.lang.String"; | |
317 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; | |
318 case JAVATYPE_ENUM : return NULL; | |
319 case JAVATYPE_MESSAGE: return NULL; | |
320 | |
321 // No default because we want the compiler to complain if any new | |
322 // JavaTypes are added. | |
323 } | |
324 | |
325 GOOGLE_LOG(FATAL) << "Can't get here."; | |
326 return NULL; | |
327 } | |
328 | |
329 const char* BoxedPrimitiveTypeName(JavaType type) { | 255 const char* BoxedPrimitiveTypeName(JavaType type) { |
330 switch (type) { | 256 switch (type) { |
331 case JAVATYPE_INT : return "java.lang.Integer"; | 257 case JAVATYPE_INT : return "java.lang.Integer"; |
332 case JAVATYPE_LONG : return "java.lang.Long"; | 258 case JAVATYPE_LONG : return "java.lang.Long"; |
333 case JAVATYPE_FLOAT : return "java.lang.Float"; | 259 case JAVATYPE_FLOAT : return "java.lang.Float"; |
334 case JAVATYPE_DOUBLE : return "java.lang.Double"; | 260 case JAVATYPE_DOUBLE : return "java.lang.Double"; |
335 case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; | 261 case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; |
336 case JAVATYPE_STRING : return "java.lang.String"; | 262 case JAVATYPE_STRING : return "java.lang.String"; |
337 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; | 263 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; |
338 case JAVATYPE_ENUM : return NULL; | 264 case JAVATYPE_ENUM : return NULL; |
339 case JAVATYPE_MESSAGE: return NULL; | 265 case JAVATYPE_MESSAGE: return NULL; |
340 | 266 |
341 // No default because we want the compiler to complain if any new | 267 // No default because we want the compiler to complain if any new |
342 // JavaTypes are added. | 268 // JavaTypes are added. |
343 } | 269 } |
344 | 270 |
345 GOOGLE_LOG(FATAL) << "Can't get here."; | 271 GOOGLE_LOG(FATAL) << "Can't get here."; |
346 return NULL; | 272 return NULL; |
347 } | 273 } |
348 | 274 |
349 const char* FieldTypeName(FieldDescriptor::Type field_type) { | |
350 switch (field_type) { | |
351 case FieldDescriptor::TYPE_INT32 : return "INT32"; | |
352 case FieldDescriptor::TYPE_UINT32 : return "UINT32"; | |
353 case FieldDescriptor::TYPE_SINT32 : return "SINT32"; | |
354 case FieldDescriptor::TYPE_FIXED32 : return "FIXED32"; | |
355 case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32"; | |
356 case FieldDescriptor::TYPE_INT64 : return "INT64"; | |
357 case FieldDescriptor::TYPE_UINT64 : return "UINT64"; | |
358 case FieldDescriptor::TYPE_SINT64 : return "SINT64"; | |
359 case FieldDescriptor::TYPE_FIXED64 : return "FIXED64"; | |
360 case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64"; | |
361 case FieldDescriptor::TYPE_FLOAT : return "FLOAT"; | |
362 case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE"; | |
363 case FieldDescriptor::TYPE_BOOL : return "BOOL"; | |
364 case FieldDescriptor::TYPE_STRING : return "STRING"; | |
365 case FieldDescriptor::TYPE_BYTES : return "BYTES"; | |
366 case FieldDescriptor::TYPE_ENUM : return "ENUM"; | |
367 case FieldDescriptor::TYPE_GROUP : return "GROUP"; | |
368 case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE"; | |
369 | |
370 // No default because we want the compiler to complain if any new | |
371 // types are added. | |
372 } | |
373 | |
374 GOOGLE_LOG(FATAL) << "Can't get here."; | |
375 return NULL; | |
376 } | |
377 | |
378 bool AllAscii(const string& text) { | 275 bool AllAscii(const string& text) { |
379 for (int i = 0; i < text.size(); i++) { | 276 for (int i = 0; i < text.size(); i++) { |
380 if ((text[i] & 0x80) != 0) { | 277 if ((text[i] & 0x80) != 0) { |
381 return false; | 278 return false; |
382 } | 279 } |
383 } | 280 } |
384 return true; | 281 return true; |
385 } | 282 } |
386 | 283 |
387 string DefaultValue(const FieldDescriptor* field, bool immutable, | 284 string DefaultValue(const FieldDescriptor* field) { |
388 ClassNameResolver* name_resolver) { | |
389 // Switch on CppType since we need to know which default_value_* method | 285 // Switch on CppType since we need to know which default_value_* method |
390 // of FieldDescriptor to call. | 286 // of FieldDescriptor to call. |
391 switch (field->cpp_type()) { | 287 switch (field->cpp_type()) { |
392 case FieldDescriptor::CPPTYPE_INT32: | 288 case FieldDescriptor::CPPTYPE_INT32: |
393 return SimpleItoa(field->default_value_int32()); | 289 return SimpleItoa(field->default_value_int32()); |
394 case FieldDescriptor::CPPTYPE_UINT32: | 290 case FieldDescriptor::CPPTYPE_UINT32: |
395 // Need to print as a signed int since Java has no unsigned. | 291 // Need to print as a signed int since Java has no unsigned. |
396 return SimpleItoa(static_cast<int32>(field->default_value_uint32())); | 292 return SimpleItoa(static_cast<int32>(field->default_value_uint32())); |
397 case FieldDescriptor::CPPTYPE_INT64: | 293 case FieldDescriptor::CPPTYPE_INT64: |
398 return SimpleItoa(field->default_value_int64()) + "L"; | 294 return SimpleItoa(field->default_value_int64()) + "L"; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 return "\"" + CEscape(field->default_value_string()) + "\""; | 337 return "\"" + CEscape(field->default_value_string()) + "\""; |
442 } else { | 338 } else { |
443 // See comments in Internal.java for gory details. | 339 // See comments in Internal.java for gory details. |
444 return strings::Substitute( | 340 return strings::Substitute( |
445 "com.google.protobuf.Internal.stringDefaultValue(\"$0\")", | 341 "com.google.protobuf.Internal.stringDefaultValue(\"$0\")", |
446 CEscape(field->default_value_string())); | 342 CEscape(field->default_value_string())); |
447 } | 343 } |
448 } | 344 } |
449 | 345 |
450 case FieldDescriptor::CPPTYPE_ENUM: | 346 case FieldDescriptor::CPPTYPE_ENUM: |
451 return name_resolver->GetClassName(field->enum_type(), immutable) + "." + | 347 return ClassName(field->enum_type()) + "." + |
452 field->default_value_enum()->name(); | 348 field->default_value_enum()->name(); |
453 | 349 |
454 case FieldDescriptor::CPPTYPE_MESSAGE: | 350 case FieldDescriptor::CPPTYPE_MESSAGE: |
455 return name_resolver->GetClassName(field->message_type(), immutable) + | 351 return ClassName(field->message_type()) + ".getDefaultInstance()"; |
456 ".getDefaultInstance()"; | |
457 | 352 |
458 // No default because we want the compiler to complain if any new | 353 // No default because we want the compiler to complain if any new |
459 // types are added. | 354 // types are added. |
460 } | 355 } |
461 | 356 |
462 GOOGLE_LOG(FATAL) << "Can't get here."; | 357 GOOGLE_LOG(FATAL) << "Can't get here."; |
463 return ""; | 358 return ""; |
464 } | 359 } |
465 | 360 |
466 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { | 361 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 } | 487 } |
593 | 488 |
594 string GenerateGetBitMutableLocal(int bitIndex) { | 489 string GenerateGetBitMutableLocal(int bitIndex) { |
595 return GenerateGetBitInternal("mutable_", bitIndex); | 490 return GenerateGetBitInternal("mutable_", bitIndex); |
596 } | 491 } |
597 | 492 |
598 string GenerateSetBitMutableLocal(int bitIndex) { | 493 string GenerateSetBitMutableLocal(int bitIndex) { |
599 return GenerateSetBitInternal("mutable_", bitIndex); | 494 return GenerateSetBitInternal("mutable_", bitIndex); |
600 } | 495 } |
601 | 496 |
602 bool IsReferenceType(JavaType type) { | |
603 switch (type) { | |
604 case JAVATYPE_INT : return false; | |
605 case JAVATYPE_LONG : return false; | |
606 case JAVATYPE_FLOAT : return false; | |
607 case JAVATYPE_DOUBLE : return false; | |
608 case JAVATYPE_BOOLEAN: return false; | |
609 case JAVATYPE_STRING : return true; | |
610 case JAVATYPE_BYTES : return true; | |
611 case JAVATYPE_ENUM : return true; | |
612 case JAVATYPE_MESSAGE: return true; | |
613 | |
614 // No default because we want the compiler to complain if any new | |
615 // JavaTypes are added. | |
616 } | |
617 | |
618 GOOGLE_LOG(FATAL) << "Can't get here."; | |
619 return false; | |
620 } | |
621 | |
622 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) { | |
623 switch (GetType(field)) { | |
624 case FieldDescriptor::TYPE_INT32 : return "Int32"; | |
625 case FieldDescriptor::TYPE_UINT32 : return "UInt32"; | |
626 case FieldDescriptor::TYPE_SINT32 : return "SInt32"; | |
627 case FieldDescriptor::TYPE_FIXED32 : return "Fixed32"; | |
628 case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; | |
629 case FieldDescriptor::TYPE_INT64 : return "Int64"; | |
630 case FieldDescriptor::TYPE_UINT64 : return "UInt64"; | |
631 case FieldDescriptor::TYPE_SINT64 : return "SInt64"; | |
632 case FieldDescriptor::TYPE_FIXED64 : return "Fixed64"; | |
633 case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; | |
634 case FieldDescriptor::TYPE_FLOAT : return "Float"; | |
635 case FieldDescriptor::TYPE_DOUBLE : return "Double"; | |
636 case FieldDescriptor::TYPE_BOOL : return "Bool"; | |
637 case FieldDescriptor::TYPE_STRING : return "String"; | |
638 case FieldDescriptor::TYPE_BYTES : { | |
639 return "Bytes"; | |
640 } | |
641 case FieldDescriptor::TYPE_ENUM : return "Enum"; | |
642 case FieldDescriptor::TYPE_GROUP : return "Group"; | |
643 case FieldDescriptor::TYPE_MESSAGE : return "Message"; | |
644 | |
645 // No default because we want the compiler to complain if any new | |
646 // types are added. | |
647 } | |
648 | |
649 GOOGLE_LOG(FATAL) << "Can't get here."; | |
650 return NULL; | |
651 } | |
652 | |
653 // For encodings with fixed sizes, returns that size in bytes. Otherwise | |
654 // returns -1. | |
655 int FixedSize(FieldDescriptor::Type type) { | |
656 switch (type) { | |
657 case FieldDescriptor::TYPE_INT32 : return -1; | |
658 case FieldDescriptor::TYPE_INT64 : return -1; | |
659 case FieldDescriptor::TYPE_UINT32 : return -1; | |
660 case FieldDescriptor::TYPE_UINT64 : return -1; | |
661 case FieldDescriptor::TYPE_SINT32 : return -1; | |
662 case FieldDescriptor::TYPE_SINT64 : return -1; | |
663 case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; | |
664 case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; | |
665 case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; | |
666 case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; | |
667 case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; | |
668 case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; | |
669 | |
670 case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; | |
671 case FieldDescriptor::TYPE_ENUM : return -1; | |
672 | |
673 case FieldDescriptor::TYPE_STRING : return -1; | |
674 case FieldDescriptor::TYPE_BYTES : return -1; | |
675 case FieldDescriptor::TYPE_GROUP : return -1; | |
676 case FieldDescriptor::TYPE_MESSAGE : return -1; | |
677 | |
678 // No default because we want the compiler to complain if any new | |
679 // types are added. | |
680 } | |
681 GOOGLE_LOG(FATAL) << "Can't get here."; | |
682 return -1; | |
683 } | |
684 | |
685 // Sort the fields of the given Descriptor by number into a new[]'d array | |
686 // and return it. The caller should delete the returned array. | |
687 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { | |
688 const FieldDescriptor** fields = | |
689 new const FieldDescriptor*[descriptor->field_count()]; | |
690 for (int i = 0; i < descriptor->field_count(); i++) { | |
691 fields[i] = descriptor->field(i); | |
692 } | |
693 std::sort(fields, fields + descriptor->field_count(), | |
694 FieldOrderingByNumber()); | |
695 return fields; | |
696 } | |
697 | |
698 // Returns true if the message type has any required fields. If it doesn't, | |
699 // we can optimize out calls to its isInitialized() method. | |
700 // | |
701 // already_seen is used to avoid checking the same type multiple times | |
702 // (and also to protect against recursion). | |
703 bool HasRequiredFields( | |
704 const Descriptor* type, | |
705 hash_set<const Descriptor*>* already_seen) { | |
706 if (already_seen->count(type) > 0) { | |
707 // The type is already in cache. This means that either: | |
708 // a. The type has no required fields. | |
709 // b. We are in the midst of checking if the type has required fields, | |
710 // somewhere up the stack. In this case, we know that if the type | |
711 // has any required fields, they'll be found when we return to it, | |
712 // and the whole call to HasRequiredFields() will return true. | |
713 // Therefore, we don't have to check if this type has required fields | |
714 // here. | |
715 return false; | |
716 } | |
717 already_seen->insert(type); | |
718 | |
719 // If the type has extensions, an extension with message type could contain | |
720 // required fields, so we have to be conservative and assume such an | |
721 // extension exists. | |
722 if (type->extension_range_count() > 0) return true; | |
723 | |
724 for (int i = 0; i < type->field_count(); i++) { | |
725 const FieldDescriptor* field = type->field(i); | |
726 if (field->is_required()) { | |
727 return true; | |
728 } | |
729 if (GetJavaType(field) == JAVATYPE_MESSAGE) { | |
730 if (HasRequiredFields(field->message_type(), already_seen)) { | |
731 return true; | |
732 } | |
733 } | |
734 } | |
735 | |
736 return false; | |
737 } | |
738 | |
739 bool HasRequiredFields(const Descriptor* type) { | |
740 hash_set<const Descriptor*> already_seen; | |
741 return HasRequiredFields(type, &already_seen); | |
742 } | |
743 | |
744 bool HasRepeatedFields(const Descriptor* descriptor) { | |
745 for (int i = 0; i < descriptor->field_count(); ++i) { | |
746 const FieldDescriptor* field = descriptor->field(i); | |
747 if (field->is_repeated()) { | |
748 return true; | |
749 } | |
750 } | |
751 return false; | |
752 } | |
753 | |
754 } // namespace java | 497 } // namespace java |
755 } // namespace compiler | 498 } // namespace compiler |
756 } // namespace protobuf | 499 } // namespace protobuf |
757 } // namespace google | 500 } // namespace google |
OLD | NEW |