This can cause ODR violations in downstream users who link against both the bootstrapped proto and transitive C++ gencode of java_features.proto. Once protoc is split up, we can turn the bootstrapped proto into a real cc_proto_library target and avoid this problem altogether. PiperOrigin-RevId: 630099889pull/16713/head
parent
d3b2fc52a4
commit
2257232676
15 changed files with 213 additions and 119 deletions
@ -0,0 +1,114 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#include "google/protobuf/compiler/java/internal_helpers.h" |
||||
|
||||
#include "absl/log/absl_log.h" |
||||
#include "google/protobuf/compiler/java/helpers.h" |
||||
#include "google/protobuf/compiler/java/name_resolver.h" |
||||
#include "google/protobuf/descriptor.pb.h" |
||||
|
||||
// Must be last.
|
||||
#include "google/protobuf/port_def.inc" |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace java { |
||||
namespace { |
||||
|
||||
int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) { |
||||
// j/c/g/protobuf/FieldType.java lists field types in a slightly different
|
||||
// order from FieldDescriptor::Type so we can't do a simple cast.
|
||||
//
|
||||
// TODO: Make j/c/g/protobuf/FieldType.java follow the same order.
|
||||
int result = field->type(); |
||||
if (result == FieldDescriptor::TYPE_GROUP) { |
||||
return 17; |
||||
} else if (result < FieldDescriptor::TYPE_GROUP) { |
||||
return result - 1; |
||||
} else { |
||||
return result - 2; |
||||
} |
||||
} |
||||
|
||||
int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) { |
||||
if (field->type() == FieldDescriptor::TYPE_GROUP) { |
||||
return 49; |
||||
} else { |
||||
return GetExperimentalJavaFieldTypeForSingular(field) + 18; |
||||
} |
||||
} |
||||
|
||||
int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) { |
||||
int result = field->type(); |
||||
if (result < FieldDescriptor::TYPE_STRING) { |
||||
return result + 34; |
||||
} else if (result > FieldDescriptor::TYPE_BYTES) { |
||||
return result + 30; |
||||
} else { |
||||
ABSL_LOG(FATAL) << field->full_name() << " can't be packed."; |
||||
return 0; |
||||
} |
||||
} |
||||
} // namespace
|
||||
|
||||
int GetExperimentalJavaFieldType(const FieldDescriptor* field) { |
||||
static const int kMapFieldType = 50; |
||||
static const int kOneofFieldTypeOffset = 51; |
||||
|
||||
static const int kRequiredBit = 0x100; |
||||
static const int kUtf8CheckBit = 0x200; |
||||
static const int kCheckInitialized = 0x400; |
||||
static const int kLegacyEnumIsClosedBit = 0x800; |
||||
static const int kHasHasBit = 0x1000; |
||||
int extra_bits = field->is_required() ? kRequiredBit : 0; |
||||
if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) { |
||||
extra_bits |= kUtf8CheckBit; |
||||
} |
||||
if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE && |
||||
HasRequiredFields(field->message_type()))) { |
||||
extra_bits |= kCheckInitialized; |
||||
} |
||||
if (HasHasbit(field)) { |
||||
extra_bits |= kHasHasBit; |
||||
} |
||||
if (GetJavaType(field) == JAVATYPE_ENUM && !SupportUnknownEnumValue(field)) { |
||||
extra_bits |= kLegacyEnumIsClosedBit; |
||||
} |
||||
|
||||
if (field->is_map()) { |
||||
if (!SupportUnknownEnumValue(MapValueField(field))) { |
||||
const FieldDescriptor* value = field->message_type()->map_value(); |
||||
if (GetJavaType(value) == JAVATYPE_ENUM) { |
||||
extra_bits |= kLegacyEnumIsClosedBit; |
||||
} |
||||
} |
||||
return kMapFieldType | extra_bits; |
||||
} else if (field->is_packed()) { |
||||
return GetExperimentalJavaFieldTypeForPacked(field) | extra_bits; |
||||
} else if (field->is_repeated()) { |
||||
return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits; |
||||
} else if (IsRealOneof(field)) { |
||||
return (GetExperimentalJavaFieldTypeForSingular(field) + |
||||
kOneofFieldTypeOffset) | |
||||
extra_bits; |
||||
} else { |
||||
return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits; |
||||
} |
||||
} |
||||
|
||||
} // namespace java
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include "google/protobuf/port_undef.inc" |
@ -0,0 +1,69 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_INTERNAL_HELPERS_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_JAVA_INTERNAL_HELPERS_H__ |
||||
|
||||
#include "google/protobuf/compiler/java/generator.h" |
||||
#include "google/protobuf/compiler/java/java_features.pb.h" |
||||
#include "google/protobuf/compiler/java/names.h" |
||||
#include "google/protobuf/descriptor.h" |
||||
#include "google/protobuf/descriptor.pb.h" |
||||
|
||||
// Must be last.
|
||||
#include "google/protobuf/port_def.inc" |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace java { |
||||
|
||||
// Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
|
||||
// but in the message and can be queried using additional getters that return
|
||||
// ints.
|
||||
inline bool SupportUnknownEnumValue(const FieldDescriptor* field) { |
||||
if (JavaGenerator::GetResolvedSourceFeatures(*field) |
||||
.GetExtension(pb::java) |
||||
.legacy_closed_enum()) { |
||||
return false; |
||||
} |
||||
return field->enum_type() != nullptr && !field->enum_type()->is_closed(); |
||||
} |
||||
|
||||
inline bool CheckUtf8(const FieldDescriptor* descriptor) { |
||||
if (JavaGenerator::GetResolvedSourceFeatures(*descriptor) |
||||
.GetExtension(pb::java) |
||||
.utf8_validation() == pb::JavaFeatures::VERIFY) { |
||||
return true; |
||||
} |
||||
return JavaGenerator::GetResolvedSourceFeatures(*descriptor) |
||||
.utf8_validation() == FeatureSet::VERIFY || |
||||
// For legacy syntax. This is not allowed under Editions.
|
||||
descriptor->file()->options().java_string_check_utf8(); |
||||
} |
||||
|
||||
// Only the lowest two bytes of the return value are used. The lowest byte
|
||||
// is the integer value of a j/c/g/protobuf/FieldType enum. For the other
|
||||
// byte:
|
||||
// bit 0: whether the field is required.
|
||||
// bit 1: whether the field requires UTF-8 validation.
|
||||
// bit 2: whether the field needs isInitialized check.
|
||||
// bit 3: whether the field is a map field with proto2 enum value.
|
||||
// bits 4-7: unused
|
||||
int GetExperimentalJavaFieldType(const FieldDescriptor* field); |
||||
|
||||
} // namespace java
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include "google/protobuf/port_undef.inc" |
||||
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_INTERNAL_HELPERS_H__
|
Loading…
Reference in new issue