1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 // Author: kenton@google.com (Kenton Varda) 9 // Based on original Protocol Buffers design by 10 // Sanjay Ghemawat, Jeff Dean, and others. 11 12 #include "google/protobuf/compiler/java/internal_helpers.h" 13 14 #include <algorithm> 15 #include <cmath> 16 #include <string> 17 #include <utility> 18 #include <vector> 19 20 #include "absl/log/absl_log.h" 21 #include "absl/strings/str_cat.h" 22 #include "absl/strings/str_format.h" 23 #include "absl/strings/str_join.h" 24 #include "absl/strings/string_view.h" 25 #include "google/protobuf/compiler/java/context.h" 26 #include "google/protobuf/compiler/java/doc_comment.h" 27 #include "google/protobuf/compiler/java/helpers.h" 28 #include "google/protobuf/compiler/java/name_resolver.h" 29 #include "google/protobuf/descriptor.h" 30 #include "google/protobuf/descriptor.pb.h" 31 32 // Must be last. 33 #include "google/protobuf/port_def.inc" 34 35 namespace google { 36 namespace protobuf { 37 namespace compiler { 38 namespace java { 39 namespace { 40 GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor * field)41int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) { 42 // j/c/g/protobuf/FieldType.java lists field types in a slightly different 43 // order from FieldDescriptor::Type so we can't do a simple cast. 44 // 45 // TODO: Make j/c/g/protobuf/FieldType.java follow the same order. 46 int result = field->type(); 47 if (result == FieldDescriptor::TYPE_GROUP) { 48 return 17; 49 } else if (result < FieldDescriptor::TYPE_GROUP) { 50 return result - 1; 51 } else { 52 return result - 2; 53 } 54 } 55 GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor * field)56int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) { 57 if (field->type() == FieldDescriptor::TYPE_GROUP) { 58 return 49; 59 } else { 60 return GetExperimentalJavaFieldTypeForSingular(field) + 18; 61 } 62 } 63 GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor * field)64int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) { 65 int result = field->type(); 66 if (result < FieldDescriptor::TYPE_STRING) { 67 return result + 34; 68 } else if (result > FieldDescriptor::TYPE_BYTES) { 69 return result + 30; 70 } else { 71 ABSL_LOG(FATAL) << field->full_name() << " can't be packed."; 72 return 0; 73 } 74 } 75 } // namespace 76 GetExperimentalJavaFieldType(const FieldDescriptor * field)77int GetExperimentalJavaFieldType(const FieldDescriptor* field) { 78 static const int kMapFieldType = 50; 79 static const int kOneofFieldTypeOffset = 51; 80 81 static const int kRequiredBit = 0x100; 82 static const int kUtf8CheckBit = 0x200; 83 static const int kCheckInitialized = 0x400; 84 static const int kLegacyEnumIsClosedBit = 0x800; 85 static const int kHasHasBit = 0x1000; 86 int extra_bits = field->is_required() ? kRequiredBit : 0; 87 if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) { 88 extra_bits |= kUtf8CheckBit; 89 } 90 if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE && 91 HasRequiredFields(field->message_type()))) { 92 extra_bits |= kCheckInitialized; 93 } 94 if (HasHasbit(field)) { 95 extra_bits |= kHasHasBit; 96 } 97 if (GetJavaType(field) == JAVATYPE_ENUM && !SupportUnknownEnumValue(field)) { 98 extra_bits |= kLegacyEnumIsClosedBit; 99 } 100 101 if (field->is_map()) { 102 if (!SupportUnknownEnumValue(MapValueField(field))) { 103 const FieldDescriptor* value = field->message_type()->map_value(); 104 if (GetJavaType(value) == JAVATYPE_ENUM) { 105 extra_bits |= kLegacyEnumIsClosedBit; 106 } 107 } 108 return kMapFieldType | extra_bits; 109 } else if (field->is_packed()) { 110 return GetExperimentalJavaFieldTypeForPacked(field) | extra_bits; 111 } else if (field->is_repeated()) { 112 return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits; 113 } else if (IsRealOneof(field)) { 114 return (GetExperimentalJavaFieldTypeForSingular(field) + 115 kOneofFieldTypeOffset) | 116 extra_bits; 117 } else { 118 return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits; 119 } 120 } 121 122 123 } // namespace java 124 } // namespace compiler 125 } // namespace protobuf 126 } // namespace google 127 128 #include "google/protobuf/port_undef.inc" 129