| 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 |