Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update defines Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <limits>
36 #include <vector>
37
38 #include <google/protobuf/compiler/java/java_helpers.h>
39 #include <google/protobuf/descriptor.pb.h>
40 #include <google/protobuf/stubs/strutil.h>
41 #include <google/protobuf/stubs/substitute.h>
42
43 namespace google {
44 namespace protobuf {
45 namespace compiler {
46 namespace java {
47
48 const char kThickSeparator[] =
49 "// ===================================================================\n";
50 const char kThinSeparator[] =
51 "// -------------------------------------------------------------------\n";
52
53 namespace {
54
55 const char* kDefaultPackage = "";
56
57 const string& FieldName(const FieldDescriptor* field) {
58 // Groups are hacky: The name of the field is just the lower-cased name
59 // of the group type. In Java, though, we would like to retain the original
60 // capitalization of the type name.
61 if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
62 return field->message_type()->name();
63 } else {
64 return field->name();
65 }
66 }
67
68 string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
69 string result;
70 // Note: I distrust ctype.h due to locales.
71 for (int i = 0; i < input.size(); i++) {
72 if ('a' <= input[i] && input[i] <= 'z') {
73 if (cap_next_letter) {
74 result += input[i] + ('A' - 'a');
75 } else {
76 result += input[i];
77 }
78 cap_next_letter = false;
79 } else if ('A' <= input[i] && input[i] <= 'Z') {
80 if (i == 0 && !cap_next_letter) {
81 // Force first letter to lower-case unless explicitly told to
82 // capitalize it.
83 result += input[i] + ('a' - 'A');
84 } else {
85 // Capital letters after the first are left as-is.
86 result += input[i];
87 }
88 cap_next_letter = false;
89 } else if ('0' <= input[i] && input[i] <= '9') {
90 result += input[i];
91 cap_next_letter = true;
92 } else {
93 cap_next_letter = true;
94 }
95 }
96 return result;
97 }
98
99 } // namespace
100
101 string UnderscoresToCamelCase(const FieldDescriptor* field) {
102 return UnderscoresToCamelCaseImpl(FieldName(field), false);
103 }
104
105 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
106 return UnderscoresToCamelCaseImpl(FieldName(field), true);
107 }
108
109 string UnderscoresToCamelCase(const MethodDescriptor* method) {
110 return UnderscoresToCamelCaseImpl(method->name(), false);
111 }
112
113 string StripProto(const string& filename) {
114 if (HasSuffixString(filename, ".protodevel")) {
115 return StripSuffixString(filename, ".protodevel");
116 } else {
117 return StripSuffixString(filename, ".proto");
118 }
119 }
120
121 string FileClassName(const FileDescriptor* file) {
122 if (file->options().has_java_outer_classname()) {
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 }
134 }
135
136 string FileJavaPackage(const FileDescriptor* file) {
137 string result;
138
139 if (file->options().has_java_package()) {
140 result = file->options().java_package();
141 } else {
142 result = kDefaultPackage;
143 if (!file->package().empty()) {
144 if (!result.empty()) result += '.';
145 result += file->package();
146 }
147 }
148
149
150 return result;
151 }
152
153 string JavaPackageToDir(string package_name) {
154 string package_dir =
155 StringReplace(package_name, ".", "/", true);
156 if (!package_dir.empty()) package_dir += "/";
157 return package_dir;
158 }
159
160 string ToJavaName(const string& full_name, const FileDescriptor* file) {
161 string result;
162 if (file->options().java_multiple_files()) {
163 result = FileJavaPackage(file);
164 } else {
165 result = ClassName(file);
166 }
167 if (!result.empty()) {
168 result += '.';
169 }
170 if (file->package().empty()) {
171 result += full_name;
172 } else {
173 // Strip the proto package from full_name since we've replaced it with
174 // the Java package.
175 result += full_name.substr(file->package().size() + 1);
176 }
177 return result;
178 }
179
180 string ClassName(const Descriptor* descriptor) {
181 return ToJavaName(descriptor->full_name(), descriptor->file());
182 }
183
184 string ClassName(const EnumDescriptor* descriptor) {
185 return ToJavaName(descriptor->full_name(), descriptor->file());
186 }
187
188 string ClassName(const ServiceDescriptor* descriptor) {
189 return ToJavaName(descriptor->full_name(), descriptor->file());
190 }
191
192 string ClassName(const FileDescriptor* descriptor) {
193 string result = FileJavaPackage(descriptor);
194 if (!result.empty()) result += '.';
195 result += FileClassName(descriptor);
196 return result;
197 }
198
199 string FieldConstantName(const FieldDescriptor *field) {
200 string name = field->name() + "_FIELD_NUMBER";
201 UpperString(&name);
202 return name;
203 }
204
205 FieldDescriptor::Type GetType(const FieldDescriptor* field) {
206 return field->type();
207 }
208
209 JavaType GetJavaType(const FieldDescriptor* field) {
210 switch (GetType(field)) {
211 case FieldDescriptor::TYPE_INT32:
212 case FieldDescriptor::TYPE_UINT32:
213 case FieldDescriptor::TYPE_SINT32:
214 case FieldDescriptor::TYPE_FIXED32:
215 case FieldDescriptor::TYPE_SFIXED32:
216 return JAVATYPE_INT;
217
218 case FieldDescriptor::TYPE_INT64:
219 case FieldDescriptor::TYPE_UINT64:
220 case FieldDescriptor::TYPE_SINT64:
221 case FieldDescriptor::TYPE_FIXED64:
222 case FieldDescriptor::TYPE_SFIXED64:
223 return JAVATYPE_LONG;
224
225 case FieldDescriptor::TYPE_FLOAT:
226 return JAVATYPE_FLOAT;
227
228 case FieldDescriptor::TYPE_DOUBLE:
229 return JAVATYPE_DOUBLE;
230
231 case FieldDescriptor::TYPE_BOOL:
232 return JAVATYPE_BOOLEAN;
233
234 case FieldDescriptor::TYPE_STRING:
235 return JAVATYPE_STRING;
236
237 case FieldDescriptor::TYPE_BYTES:
238 return JAVATYPE_BYTES;
239
240 case FieldDescriptor::TYPE_ENUM:
241 return JAVATYPE_ENUM;
242
243 case FieldDescriptor::TYPE_GROUP:
244 case FieldDescriptor::TYPE_MESSAGE:
245 return JAVATYPE_MESSAGE;
246
247 // No default because we want the compiler to complain if any new
248 // types are added.
249 }
250
251 GOOGLE_LOG(FATAL) << "Can't get here.";
252 return JAVATYPE_INT;
253 }
254
255 const char* BoxedPrimitiveTypeName(JavaType type) {
256 switch (type) {
257 case JAVATYPE_INT : return "java.lang.Integer";
258 case JAVATYPE_LONG : return "java.lang.Long";
259 case JAVATYPE_FLOAT : return "java.lang.Float";
260 case JAVATYPE_DOUBLE : return "java.lang.Double";
261 case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
262 case JAVATYPE_STRING : return "java.lang.String";
263 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
264 case JAVATYPE_ENUM : return NULL;
265 case JAVATYPE_MESSAGE: return NULL;
266
267 // No default because we want the compiler to complain if any new
268 // JavaTypes are added.
269 }
270
271 GOOGLE_LOG(FATAL) << "Can't get here.";
272 return NULL;
273 }
274
275 bool AllAscii(const string& text) {
276 for (int i = 0; i < text.size(); i++) {
277 if ((text[i] & 0x80) != 0) {
278 return false;
279 }
280 }
281 return true;
282 }
283
284 string DefaultValue(const FieldDescriptor* field) {
285 // Switch on CppType since we need to know which default_value_* method
286 // of FieldDescriptor to call.
287 switch (field->cpp_type()) {
288 case FieldDescriptor::CPPTYPE_INT32:
289 return SimpleItoa(field->default_value_int32());
290 case FieldDescriptor::CPPTYPE_UINT32:
291 // Need to print as a signed int since Java has no unsigned.
292 return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
293 case FieldDescriptor::CPPTYPE_INT64:
294 return SimpleItoa(field->default_value_int64()) + "L";
295 case FieldDescriptor::CPPTYPE_UINT64:
296 return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
297 "L";
298 case FieldDescriptor::CPPTYPE_DOUBLE: {
299 double value = field->default_value_double();
300 if (value == numeric_limits<double>::infinity()) {
301 return "Double.POSITIVE_INFINITY";
302 } else if (value == -numeric_limits<double>::infinity()) {
303 return "Double.NEGATIVE_INFINITY";
304 } else if (value != value) {
305 return "Double.NaN";
306 } else {
307 return SimpleDtoa(value) + "D";
308 }
309 }
310 case FieldDescriptor::CPPTYPE_FLOAT: {
311 float value = field->default_value_float();
312 if (value == numeric_limits<float>::infinity()) {
313 return "Float.POSITIVE_INFINITY";
314 } else if (value == -numeric_limits<float>::infinity()) {
315 return "Float.NEGATIVE_INFINITY";
316 } else if (value != value) {
317 return "Float.NaN";
318 } else {
319 return SimpleFtoa(value) + "F";
320 }
321 }
322 case FieldDescriptor::CPPTYPE_BOOL:
323 return field->default_value_bool() ? "true" : "false";
324 case FieldDescriptor::CPPTYPE_STRING:
325 if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
326 if (field->has_default_value()) {
327 // See comments in Internal.java for gory details.
328 return strings::Substitute(
329 "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
330 CEscape(field->default_value_string()));
331 } else {
332 return "com.google.protobuf.ByteString.EMPTY";
333 }
334 } else {
335 if (AllAscii(field->default_value_string())) {
336 // All chars are ASCII. In this case CEscape() works fine.
337 return "\"" + CEscape(field->default_value_string()) + "\"";
338 } else {
339 // See comments in Internal.java for gory details.
340 return strings::Substitute(
341 "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
342 CEscape(field->default_value_string()));
343 }
344 }
345
346 case FieldDescriptor::CPPTYPE_ENUM:
347 return ClassName(field->enum_type()) + "." +
348 field->default_value_enum()->name();
349
350 case FieldDescriptor::CPPTYPE_MESSAGE:
351 return ClassName(field->message_type()) + ".getDefaultInstance()";
352
353 // No default because we want the compiler to complain if any new
354 // types are added.
355 }
356
357 GOOGLE_LOG(FATAL) << "Can't get here.";
358 return "";
359 }
360
361 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
362 // Switch on CppType since we need to know which default_value_* method
363 // of FieldDescriptor to call.
364 switch (field->cpp_type()) {
365 case FieldDescriptor::CPPTYPE_INT32:
366 return field->default_value_int32() == 0;
367 case FieldDescriptor::CPPTYPE_UINT32:
368 return field->default_value_uint32() == 0;
369 case FieldDescriptor::CPPTYPE_INT64:
370 return field->default_value_int64() == 0L;
371 case FieldDescriptor::CPPTYPE_UINT64:
372 return field->default_value_uint64() == 0L;
373 case FieldDescriptor::CPPTYPE_DOUBLE:
374 return field->default_value_double() == 0.0;
375 case FieldDescriptor::CPPTYPE_FLOAT:
376 return field->default_value_float() == 0.0;
377 case FieldDescriptor::CPPTYPE_BOOL:
378 return field->default_value_bool() == false;
379
380 case FieldDescriptor::CPPTYPE_STRING:
381 case FieldDescriptor::CPPTYPE_ENUM:
382 case FieldDescriptor::CPPTYPE_MESSAGE:
383 return false;
384
385 // No default because we want the compiler to complain if any new
386 // types are added.
387 }
388
389 GOOGLE_LOG(FATAL) << "Can't get here.";
390 return false;
391 }
392
393 const char* bit_masks[] = {
394 "0x00000001",
395 "0x00000002",
396 "0x00000004",
397 "0x00000008",
398 "0x00000010",
399 "0x00000020",
400 "0x00000040",
401 "0x00000080",
402
403 "0x00000100",
404 "0x00000200",
405 "0x00000400",
406 "0x00000800",
407 "0x00001000",
408 "0x00002000",
409 "0x00004000",
410 "0x00008000",
411
412 "0x00010000",
413 "0x00020000",
414 "0x00040000",
415 "0x00080000",
416 "0x00100000",
417 "0x00200000",
418 "0x00400000",
419 "0x00800000",
420
421 "0x01000000",
422 "0x02000000",
423 "0x04000000",
424 "0x08000000",
425 "0x10000000",
426 "0x20000000",
427 "0x40000000",
428 "0x80000000",
429 };
430
431 string GetBitFieldName(int index) {
432 string varName = "bitField";
433 varName += SimpleItoa(index);
434 varName += "_";
435 return varName;
436 }
437
438 string GetBitFieldNameForBit(int bitIndex) {
439 return GetBitFieldName(bitIndex / 32);
440 }
441
442 namespace {
443
444 string GenerateGetBitInternal(const string& prefix, int bitIndex) {
445 string varName = prefix + GetBitFieldNameForBit(bitIndex);
446 int bitInVarIndex = bitIndex % 32;
447
448 string mask = bit_masks[bitInVarIndex];
449 string result = "((" + varName + " & " + mask + ") == " + mask + ")";
450 return result;
451 }
452
453 string GenerateSetBitInternal(const string& prefix, int bitIndex) {
454 string varName = prefix + GetBitFieldNameForBit(bitIndex);
455 int bitInVarIndex = bitIndex % 32;
456
457 string mask = bit_masks[bitInVarIndex];
458 string result = varName + " |= " + mask;
459 return result;
460 }
461
462 } // namespace
463
464 string GenerateGetBit(int bitIndex) {
465 return GenerateGetBitInternal("", bitIndex);
466 }
467
468 string GenerateSetBit(int bitIndex) {
469 return GenerateSetBitInternal("", bitIndex);
470 }
471
472 string GenerateClearBit(int bitIndex) {
473 string varName = GetBitFieldNameForBit(bitIndex);
474 int bitInVarIndex = bitIndex % 32;
475
476 string mask = bit_masks[bitInVarIndex];
477 string result = varName + " = (" + varName + " & ~" + mask + ")";
478 return result;
479 }
480
481 string GenerateGetBitFromLocal(int bitIndex) {
482 return GenerateGetBitInternal("from_", bitIndex);
483 }
484
485 string GenerateSetBitToLocal(int bitIndex) {
486 return GenerateSetBitInternal("to_", bitIndex);
487 }
488
489 string GenerateGetBitMutableLocal(int bitIndex) {
490 return GenerateGetBitInternal("mutable_", bitIndex);
491 }
492
493 string GenerateSetBitMutableLocal(int bitIndex) {
494 return GenerateSetBitInternal("mutable_", bitIndex);
495 }
496
497 } // namespace java
498 } // namespace compiler
499 } // namespace protobuf
500 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698