• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)41 int 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)56 int 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)64 int 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)77 int 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