Internal changes

PiperOrigin-RevId: 528038754
pull/10781/head
Mike Kruskal 2 years ago committed by Copybara-Service
parent c045343d61
commit 3c279623a0
  1. 1
      pkg/BUILD.bazel
  2. 15
      src/google/protobuf/BUILD.bazel
  3. 219
      src/google/protobuf/descriptor.cc
  4. 2
      src/google/protobuf/descriptor.h
  5. 6
      src/google/protobuf/descriptor_unittest.cc
  6. 68
      src/google/protobuf/test_textproto.h

@ -229,6 +229,7 @@ cc_dist_library(
testonly = 1,
tags = ["manual"],
deps = [
"//src/google/protobuf:test_textproto",
"//src/google/protobuf/compiler:mock_code_generator",
"//src/google/protobuf/testing",
],

@ -961,6 +961,7 @@ cc_test(
":cc_test_protos",
":descriptor_legacy",
":protobuf",
":test_textproto",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/testing",
"@com_google_absl//absl/log:die_if_null",
@ -971,6 +972,20 @@ cc_test(
],
)
cc_library(
name = "test_textproto",
testonly = True,
hdrs = ["test_textproto.h"],
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [
":protobuf",
"@com_google_googletest//:gtest",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/memory",
],
)
cc_test(
name = "drop_unknown_fields_test",
srcs = ["drop_unknown_fields_test.cc"],

@ -57,6 +57,7 @@
#include "absl/hash/hash.h"
#include "absl/log/absl_check.h"
#include "absl/log/absl_log.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/match.h"
@ -1219,10 +1220,11 @@ class FlatAllocator
: public decltype(ApplyTypeList<FlatAllocatorImpl>(
SortByAlignment<char, std::string, SourceCodeInfo,
FileDescriptorTables,
// Option types
// Option types
MessageOptions, FieldOptions, EnumOptions,
EnumValueOptions, ExtensionRangeOptions, OneofOptions,
ServiceOptions, MethodOptions, FileOptions>())) {};
ServiceOptions, MethodOptions, FileOptions>())) {
};
} // namespace internal
@ -3708,11 +3710,11 @@ namespace {
// one of the Options messages in descriptor.proto.
struct OptionsToInterpret {
OptionsToInterpret(absl::string_view ns, absl::string_view el,
const std::vector<int>& path, const Message* orig_opt,
absl::Span<const int> path, const Message* orig_opt,
Message* opt)
: name_scope(ns),
element_name(el),
element_path(path),
element_path(path.begin(), path.end()),
original_options(orig_opt),
options(opt) {}
std::string name_scope;
@ -3751,6 +3753,7 @@ class DescriptorBuilder {
DescriptorPool::Tables* tables_; // for convenience
DescriptorPool::ErrorCollector* error_collector_;
// As we build descriptors we store copies of the options messages in
// them. We put pointers to those copies in this vector, as we build, so we
// can later (after cross-linking) interpret those options.
@ -3927,22 +3930,23 @@ class DescriptorBuilder {
// later. DescriptorT must be one of the Descriptor messages from
// descriptor.proto.
template <class DescriptorT>
void AllocateOptions(const typename DescriptorT::OptionsType& orig_options,
DescriptorT* descriptor, int options_field_tag,
absl::string_view option_name,
internal::FlatAllocator& alloc);
typename DescriptorT::OptionsType* AllocateOptions(
const typename DescriptorT::Proto& proto, const DescriptorT* descriptor,
int options_field_tag, absl::string_view option_name,
internal::FlatAllocator& alloc);
// Specialization for FileOptions.
void AllocateOptions(const FileOptions& orig_options,
FileDescriptor* descriptor,
internal::FlatAllocator& alloc);
FileOptions* AllocateOptions(const FileDescriptorProto& proto,
const FileDescriptor* descriptor,
internal::FlatAllocator& alloc);
// Implementation for AllocateOptions(). Don't call this directly.
template <class DescriptorT>
void AllocateOptionsImpl(
typename DescriptorT::OptionsType* AllocateOptionsImpl(
absl::string_view name_scope, absl::string_view element_name,
const typename DescriptorT::OptionsType& orig_options,
DescriptorT* descriptor, const std::vector<int>& options_path,
absl::string_view option_name, internal::FlatAllocator& alloc);
const typename DescriptorT::Proto& proto,
absl::Span<const int> options_path, absl::string_view option_name,
internal::FlatAllocator& alloc);
// Allocates an array of two strings, the first one is a copy of `proto_name`,
// and the second one is the full name.
@ -4196,15 +4200,17 @@ class DescriptorBuilder {
// descriptors, which are the ones that have been interpreted. The const
// proto references are passed in only so they can be provided to calls to
// AddError(). Do not look at their options, which have not been interpreted.
void ValidateFileOptions(FileDescriptor* file,
void ValidateFileOptions(const FileDescriptor* file,
const FileDescriptorProto& proto);
void ValidateMessageOptions(Descriptor* message,
void ValidateMessageOptions(const Descriptor* message,
const DescriptorProto& proto);
void ValidateFieldOptions(FieldDescriptor* field,
void ValidateOneofOptions(const OneofDescriptor* oneof,
const OneofDescriptorProto& proto);
void ValidateFieldOptions(const FieldDescriptor* field,
const FieldDescriptorProto& proto);
void ValidateEnumOptions(EnumDescriptor* enm,
void ValidateEnumOptions(const EnumDescriptor* enm,
const EnumDescriptorProto& proto);
void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
void ValidateEnumValueOptions(const EnumValueDescriptor* enum_value,
const EnumValueDescriptorProto& proto);
void ValidateExtensionRangeOptions(const DescriptorProto& proto,
const Descriptor& message);
@ -4213,20 +4219,22 @@ class DescriptorBuilder {
const RepeatedPtrField<ExtensionRangeOptions_Declaration>& declarations,
const DescriptorProto_ExtensionRange& proto,
absl::flat_hash_set<absl::string_view>& full_name_set);
void ValidateServiceOptions(ServiceDescriptor* service,
void ValidateServiceOptions(const ServiceDescriptor* service,
const ServiceDescriptorProto& proto);
void ValidateMethodOptions(MethodDescriptor* method,
void ValidateMethodOptions(const MethodDescriptor* method,
const MethodDescriptorProto& proto);
void ValidateProto3(FileDescriptor* file, const FileDescriptorProto& proto);
void ValidateProto3Message(Descriptor* message, const DescriptorProto& proto);
void ValidateProto3Field(FieldDescriptor* field,
void ValidateProto3(const FileDescriptor* file,
const FileDescriptorProto& proto);
void ValidateProto3Message(const Descriptor* message,
const DescriptorProto& proto);
void ValidateProto3Field(const FieldDescriptor* field,
const FieldDescriptorProto& proto);
void ValidateProto3Enum(EnumDescriptor* enm,
void ValidateProto3Enum(const EnumDescriptor* enm,
const EnumDescriptorProto& proto);
// Returns true if the map entry message is compatible with the
// auto-generated entry message from map fields syntax.
bool ValidateMapEntry(FieldDescriptor* field,
bool ValidateMapEntry(const FieldDescriptor* field,
const FieldDescriptorProto& proto);
// Recursively detects naming conflicts with map entry types for a
@ -4234,7 +4242,7 @@ class DescriptorBuilder {
void DetectMapConflicts(const Descriptor* message,
const DescriptorProto& proto);
void ValidateJSType(FieldDescriptor* field,
void ValidateJSType(const FieldDescriptor* field,
const FieldDescriptorProto& proto);
};
@ -4850,43 +4858,49 @@ void DescriptorBuilder::ValidateSymbolName(const std::string& name,
// This generic implementation is good for all descriptors except
// FileDescriptor.
template <class DescriptorT>
void DescriptorBuilder::AllocateOptions(
const typename DescriptorT::OptionsType& orig_options,
DescriptorT* descriptor, int options_field_tag,
absl::string_view option_name, internal::FlatAllocator& alloc) {
typename DescriptorT::OptionsType* DescriptorBuilder::AllocateOptions(
const typename DescriptorT::Proto& proto, const DescriptorT* descriptor,
int options_field_tag, absl::string_view option_name,
internal::FlatAllocator& alloc) {
std::vector<int> options_path;
descriptor->GetLocationPath(&options_path);
options_path.push_back(options_field_tag);
AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
orig_options, descriptor, options_path, option_name,
alloc);
return AllocateOptionsImpl<DescriptorT>(descriptor->full_name(),
descriptor->full_name(), proto,
options_path, option_name, alloc);
}
// We specialize for FileDescriptor.
void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
FileDescriptor* descriptor,
internal::FlatAllocator& alloc) {
FileOptions* DescriptorBuilder::AllocateOptions(
const FileDescriptorProto& proto, const FileDescriptor* descriptor,
internal::FlatAllocator& alloc) {
std::vector<int> options_path;
options_path.push_back(FileDescriptorProto::kOptionsFieldNumber);
// We add the dummy token so that LookupSymbol does the right thing.
AllocateOptionsImpl(absl::StrCat(descriptor->package(), ".dummy"),
descriptor->name(), orig_options, descriptor,
options_path, "google.protobuf.FileOptions", alloc);
return AllocateOptionsImpl<FileDescriptor>(
absl::StrCat(descriptor->package(), ".dummy"), descriptor->name(), proto,
options_path, "google.protobuf.FileOptions", alloc);
}
template <class DescriptorT>
void DescriptorBuilder::AllocateOptionsImpl(
typename DescriptorT::OptionsType* DescriptorBuilder::AllocateOptionsImpl(
absl::string_view name_scope, absl::string_view element_name,
const typename DescriptorT::OptionsType& orig_options,
DescriptorT* descriptor, const std::vector<int>& options_path,
absl::string_view option_name, internal::FlatAllocator& alloc) {
const typename DescriptorT::Proto& proto,
absl::Span<const int> options_path, absl::string_view option_name,
internal::FlatAllocator& alloc) {
if (!proto.has_options()) {
// Set to default_instance later if necessary.
return nullptr;
}
const typename DescriptorT::OptionsType& orig_options = proto.options();
auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
if (!orig_options.IsInitialized()) {
AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
DescriptorPool::ErrorCollector::OPTION_NAME,
"Uninterpreted option is missing name or value.");
return;
return nullptr;
}
// Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
@ -4894,7 +4908,6 @@ void DescriptorBuilder::AllocateOptionsImpl(
// reflection based method, which requires the Descriptor. However, we are in
// the middle of building the descriptors, thus the deadlock.
options->ParseFromString(orig_options.SerializeAsString());
descriptor->options_ = options;
// Don't add to options_to_interpret_ unless there were uninterpreted
// options. This not only avoids unnecessary work, but prevents a
@ -4926,8 +4939,10 @@ void DescriptorBuilder::AllocateOptionsImpl(
}
}
}
return options;
}
// A common pattern: We want to convert a repeated field in the descriptor
// to an array of values, calling some method to build each value.
#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
@ -5211,6 +5226,7 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl(
FileDescriptor* result = alloc.AllocateArray<FileDescriptor>(1);
file_ = result;
result->is_placeholder_ = false;
result->finished_building_ = false;
SourceCodeInfo* info = nullptr;
@ -5310,6 +5326,7 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl(
return nullptr;
}
if (dependency == nullptr) {
if (!pool_->lazily_build_dependencies_) {
if (pool_->allow_unknown_ ||
@ -5420,9 +5437,9 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl(
BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr);
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result, alloc);
{
FileOptions* options = AllocateOptions(proto, result, alloc);
result->options_ = options; // Set to default_instance later if necessary.
}
// Note that the following steps must occur in exactly the specified order.
@ -5579,11 +5596,9 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
}
// Copy options.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
DescriptorProto::kOptionsFieldNumber,
"google.protobuf.MessageOptions", alloc);
}
result->options_ =
AllocateOptions(proto, result, DescriptorProto::kOptionsFieldNumber,
"google.protobuf.MessageOptions", alloc);
AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
@ -6073,12 +6088,9 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
}
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
FieldDescriptorProto::kOptionsFieldNumber,
"google.protobuf.FieldOptions", alloc);
}
result->options_ =
AllocateOptions(proto, result, FieldDescriptorProto::kOptionsFieldNumber,
"google.protobuf.FieldOptions", alloc);
AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
}
@ -6117,9 +6129,9 @@ void DescriptorBuilder::BuildExtensionRange(
}
options_path.push_back(index);
options_path.push_back(DescriptorProto_ExtensionRange::kOptionsFieldNumber);
AllocateOptionsImpl(parent->full_name(), parent->full_name(),
proto.options(), result, options_path,
"google.protobuf.ExtensionRangeOptions", alloc);
result->options_ = AllocateOptionsImpl<Descriptor::ExtensionRange>(
parent->full_name(), parent->full_name(), proto, options_path,
"google.protobuf.ExtensionRangeOptions", alloc);
}
}
@ -6162,14 +6174,11 @@ void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
// We need to fill these in later.
result->field_count_ = 0;
result->fields_ = nullptr;
result->options_ = nullptr;
// Copy options.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
OneofDescriptorProto::kOptionsFieldNumber,
"google.protobuf.OneofOptions", alloc);
}
result->options_ =
AllocateOptions(proto, result, OneofDescriptorProto::kOptionsFieldNumber,
"google.protobuf.OneofOptions", alloc);
AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
}
@ -6292,12 +6301,9 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
}
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
EnumDescriptorProto::kOptionsFieldNumber,
"google.protobuf.EnumOptions", alloc);
}
result->options_ =
AllocateOptions(proto, result, EnumDescriptorProto::kOptionsFieldNumber,
"google.protobuf.EnumOptions", alloc);
AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
@ -6373,12 +6379,9 @@ void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
ValidateSymbolName(proto.name(), result->full_name(), proto);
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
EnumValueDescriptorProto::kOptionsFieldNumber,
"google.protobuf.EnumValueOptions", alloc);
}
result->options_ = AllocateOptions(
proto, result, EnumValueDescriptorProto::kOptionsFieldNumber,
"google.protobuf.EnumValueOptions", alloc);
// Again, enum values are weird because we makes them appear as siblings
// of the enum type instead of children of it. So, we use
@ -6440,12 +6443,9 @@ void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
BUILD_ARRAY(proto, result, method, BuildMethod, result);
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
ServiceDescriptorProto::kOptionsFieldNumber,
"google.protobuf.ServiceOptions", alloc);
}
result->options_ = AllocateOptions(
proto, result, ServiceDescriptorProto::kOptionsFieldNumber,
"google.protobuf.ServiceOptions", alloc);
AddSymbol(result->full_name(), nullptr, result->name(), proto,
Symbol(result));
@ -6466,12 +6466,9 @@ void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
result->output_type_.Init();
// Copy options.
result->options_ = nullptr; // Set to default_instance later if necessary.
if (proto.has_options()) {
AllocateOptions(proto.options(), result,
MethodDescriptorProto::kOptionsFieldNumber,
"google.protobuf.MethodOptions", alloc);
}
result->options_ =
AllocateOptions(proto, result, MethodDescriptorProto::kOptionsFieldNumber,
"google.protobuf.MethodOptions", alloc);
result->client_streaming_ = proto.client_streaming();
result->server_streaming_ = proto.server_streaming();
@ -7127,7 +7124,7 @@ static bool IsLite(const FileDescriptor* file) {
file->options().optimize_for() == FileOptions::LITE_RUNTIME;
}
void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
void DescriptorBuilder::ValidateFileOptions(const FileDescriptor* file,
const FileDescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message);
VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum);
@ -7156,7 +7153,7 @@ void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
}
}
void DescriptorBuilder::ValidateProto3(FileDescriptor* file,
void DescriptorBuilder::ValidateProto3(const FileDescriptor* file,
const FileDescriptorProto& proto) {
for (int i = 0; i < file->extension_count(); ++i) {
ValidateProto3Field(file->extensions_ + i, proto.extension(i));
@ -7169,7 +7166,7 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file,
}
}
void DescriptorBuilder::ValidateProto3Message(Descriptor* message,
void DescriptorBuilder::ValidateProto3Message(const Descriptor* message,
const DescriptorProto& proto) {
for (int i = 0; i < message->nested_type_count(); ++i) {
ValidateProto3Message(message->nested_types_ + i, proto.nested_type(i));
@ -7195,7 +7192,7 @@ void DescriptorBuilder::ValidateProto3Message(Descriptor* message,
}
}
void DescriptorBuilder::ValidateProto3Field(FieldDescriptor* field,
void DescriptorBuilder::ValidateProto3Field(const FieldDescriptor* field,
const FieldDescriptorProto& proto) {
if (field->is_extension() &&
!AllowedExtendeeInProto3(field->containing_type()->full_name())) {
@ -7234,7 +7231,7 @@ void DescriptorBuilder::ValidateProto3Field(FieldDescriptor* field,
}
}
void DescriptorBuilder::ValidateProto3Enum(EnumDescriptor* enm,
void DescriptorBuilder::ValidateProto3Enum(const EnumDescriptor* enm,
const EnumDescriptorProto& proto) {
if (enm->value_count() > 0 && enm->value(0)->number() != 0) {
AddError(enm->full_name(), proto.value(0),
@ -7243,7 +7240,7 @@ void DescriptorBuilder::ValidateProto3Enum(EnumDescriptor* enm,
}
}
void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
void DescriptorBuilder::ValidateMessageOptions(const Descriptor* message,
const DescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message);
@ -7252,14 +7249,21 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
CheckFieldJsonNameUniqueness(proto, message);
ValidateExtensionRangeOptions(proto, *message);
for (int i = 0; i < message->real_oneof_decl_count(); ++i) {
ValidateOneofOptions(message->oneof_decl(i), proto.oneof_decl(i));
}
}
void DescriptorBuilder::ValidateOneofOptions(
const OneofDescriptor* /*oneof*/, const OneofDescriptorProto& /*proto*/) {}
void DescriptorBuilder::ValidateFieldOptions(
FieldDescriptor* field, const FieldDescriptorProto& proto) {
const FieldDescriptor* field, const FieldDescriptorProto& proto) {
if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) {
return;
}
// Only message type fields may be lazy.
if (field->options().lazy() || field->options().unverified_lazy()) {
if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
@ -7334,7 +7338,7 @@ void DescriptorBuilder::ValidateFieldOptions(
}
void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
void DescriptorBuilder::ValidateEnumOptions(const EnumDescriptor* enm,
const EnumDescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue);
@ -7380,7 +7384,7 @@ void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
}
void DescriptorBuilder::ValidateEnumValueOptions(
EnumValueDescriptor* /* enum_value */,
const EnumValueDescriptor* /* enum_value */,
const EnumValueDescriptorProto& /* proto */) {
// Nothing to do so far.
}
@ -7521,7 +7525,7 @@ void DescriptorBuilder::ValidateExtensionRangeOptions(
}
void DescriptorBuilder::ValidateServiceOptions(
ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
const ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
if (IsLite(service->file()) &&
(service->file()->options().cc_generic_services() ||
service->file()->options().java_generic_services())) {
@ -7535,11 +7539,12 @@ void DescriptorBuilder::ValidateServiceOptions(
}
void DescriptorBuilder::ValidateMethodOptions(
MethodDescriptor* /* method */, const MethodDescriptorProto& /* proto */) {
const MethodDescriptor* /* method */,
const MethodDescriptorProto& /* proto */) {
// Nothing to do so far.
}
bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field,
bool DescriptorBuilder::ValidateMapEntry(const FieldDescriptor* field,
const FieldDescriptorProto& proto) {
const Descriptor* message = field->message_type();
if ( // Must not contain extensions, extension range or nested message or
@ -7675,7 +7680,7 @@ void DescriptorBuilder::DetectMapConflicts(const Descriptor* message,
}
}
void DescriptorBuilder::ValidateJSType(FieldDescriptor* field,
void DescriptorBuilder::ValidateJSType(const FieldDescriptor* field,
const FieldDescriptorProto& proto) {
FieldOptions::JSType jstype = field->options().jstype();
// The default is always acceptable.

@ -120,6 +120,7 @@ class ServiceOptions;
class MethodOptions;
class FileOptions;
class UninterpretedOption;
class FeatureSet;
class SourceCodeInfo;
// Defined in message.h
@ -1676,6 +1677,7 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
const FileOptions& options() const;
private:
// With the upcoming release of editions, syntax should not be used for
// business logic. Instead, the various feature helpers defined in this file

@ -49,6 +49,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/test_textproto.h"
#include "google/protobuf/unittest.pb.h"
#include "google/protobuf/unittest_custom_options.pb.h"
#include "google/protobuf/stubs/common.h"
@ -468,7 +469,7 @@ TEST_F(FileDescriptorTest, Syntax) {
proto.set_syntax("proto2");
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(proto);
EXPECT_TRUE(file != nullptr);
ASSERT_TRUE(file != nullptr);
EXPECT_EQ(FileDescriptorLegacy::Syntax::SYNTAX_PROTO2, FileDescriptorLegacy(file).syntax());
FileDescriptorProto other;
file->CopyTo(&other);
@ -479,7 +480,7 @@ TEST_F(FileDescriptorTest, Syntax) {
proto.set_syntax("proto3");
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(proto);
EXPECT_TRUE(file != nullptr);
ASSERT_TRUE(file != nullptr);
EXPECT_EQ(FileDescriptorLegacy::Syntax::SYNTAX_PROTO3,
FileDescriptorLegacy(file).syntax());
FileDescriptorProto other;
@ -7074,6 +7075,7 @@ TEST_F(ValidationErrorTest, UnusedImportWithOtherError) {
TEST_F(ValidationErrorTest, PackageTooLong) {
BuildFileWithErrors(
"name: \"foo.proto\" "

@ -0,0 +1,68 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_TEST_TEXTPROTO_H__
#define GOOGLE_PROTOBUF_TEST_TEXTPROTO_H__
#include <gmock/gmock.h>
#include "absl/log/absl_check.h"
#include "absl/memory/memory.h"
#include "google/protobuf/text_format.h"
// This file contains private helpers for dealing with textprotos in our
// tests. We make no guarantees about the behavior in real-world situations,
// and these are only meant for basic unit-tests of protobuf internals.
namespace google {
namespace protobuf {
MATCHER_P(EqualsProto, textproto, "") {
auto msg = absl::WrapUnique(arg.New());
return TextFormat::ParseFromString(textproto, msg.get()) &&
msg->DebugString() == arg.DebugString();
}
class ParseTextOrDie {
public:
explicit ParseTextOrDie(absl::string_view text) : text_(text) {}
template <typename Proto>
operator Proto() { // NOLINT(google-explicit-constructor)
Proto ret;
ABSL_CHECK(TextFormat::ParseFromString(text_, &ret));
return ret;
}
private:
absl::string_view text_;
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_TEST_TEXTPROTO_H__
Loading…
Cancel
Save