Fix java proto generation: conflict between with enum field and another field with "_value" suffix.

PiperOrigin-RevId: 694081386
pull/19117/head
Protobuf Team Bot 4 months ago committed by Copybara-Service
parent 429c9bc5c9
commit 2a04f8bd43
  1. 17
      csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs
  2. 94
      src/google/protobuf/compiler/java/context.cc

@ -1,17 +0,0 @@
#region Copyright notice and license
// 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
#endregion
namespace Google.Protobuf.Reflection;
internal sealed partial class FeatureSetDescriptor
{
// Canonical serialized form of the edition defaults, generated by embed_edition_defaults.
private const string DefaultsBase64 =
"ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH";
}

@ -15,6 +15,7 @@
#include "absl/strings/strip.h"
#include "google/protobuf/compiler/java/field_common.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/internal_helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/descriptor.h"
@ -41,48 +42,71 @@ bool EqualWithSuffix(absl::string_view name1, absl::string_view suffix,
return name1 == name2;
}
bool IsRepeatedFieldConflicting(const FieldDescriptor* field1,
absl::string_view name1,
const FieldDescriptor* field2,
absl::string_view name2, std::string* info) {
if (field1->is_repeated() && !field2->is_repeated()) {
if (EqualWithSuffix(name1, "Count", name2)) {
*info =
absl::StrCat("both repeated field \"", field1->name(),
"\" and singular ", "field \"", field2->name(),
"\" generate the method \"", "get", name1, "Count()\"");
return true;
}
if (EqualWithSuffix(name1, "List", name2)) {
*info =
absl::StrCat("both repeated field \"", field1->name(),
"\" and singular ", "field \"", field2->name(),
"\" generate the method \"", "get", name1, "List()\"");
return true;
}
}
return false;
}
bool IsEnumFieldConflicting(const FieldDescriptor* field1,
absl::string_view name1,
const FieldDescriptor* field2,
absl::string_view name2, std::string* info) {
if (field1->type() == FieldDescriptor::TYPE_ENUM &&
SupportUnknownEnumValue(field1) &&
EqualWithSuffix(name1, "Value", name2)) {
*info = absl::StrCat(
"both enum field \"", field1->name(), "\" and regular ", "field \"",
field2->name(), "\" generate the method \"", "get", name1, "Value()\"");
return true;
}
return false;
}
// Field 1 and 2 will be called the other way around as well, so no need to
// check both ways here
bool IsConflictingOneWay(const FieldDescriptor* field1, absl::string_view name1,
const FieldDescriptor* field2, absl::string_view name2,
std::string* info) {
return IsRepeatedFieldConflicting(field1, name1, field2, name2, info) ||
IsEnumFieldConflicting(field1, name1, field2, name2, info);
// Well, there are obviously many more conflicting cases, but it probably
// doesn't worth the effort to exhaust all of them because they rarely
// happen and as we are continuing adding new methods/changing existing
// methods the number of different conflicting cases will keep growing.
// We can just add more cases here when they are found in the real world.
}
// Whether two fields have conflicting accessors (assuming name1 and name2
// are different). name1 and name2 are field1 and field2's camel-case name
// respectively.
bool IsConflicting(const FieldDescriptor* field1, absl::string_view name1,
const FieldDescriptor* field2, absl::string_view name2,
std::string* info) {
if (field1->is_repeated()) {
if (field2->is_repeated()) {
// Both fields are repeated.
return false;
} else {
// field1 is repeated, and field2 is not.
if (EqualWithSuffix(name1, "Count", name2)) {
*info = absl::StrCat("both repeated field \"", field1->name(),
"\" and singular ", "field \"", field2->name(),
"\" generate the method \"", "get", name1,
"Count()\"");
return true;
}
if (EqualWithSuffix(name1, "List", name2)) {
*info =
absl::StrCat("both repeated field \"", field1->name(),
"\" and singular ", "field \"", field2->name(),
"\" generate the method \"", "get", name1, "List()\"");
return true;
}
// Well, there are obviously many more conflicting cases, but it probably
// doesn't worth the effort to exhaust all of them because they rarely
// happen and as we are continuing adding new methods/changing existing
// methods the number of different conflicting cases will keep growing.
// We can just add more cases here when they are found in the real world.
return false;
}
} else {
if (field2->is_repeated()) {
return IsConflicting(field2, name2, field1, name1, info);
} else {
// None of the two fields are repeated.
return false;
}
}
return IsConflictingOneWay(field1, name1, field2, name2, info) ||
IsConflictingOneWay(field2, name2, field1, name1, info);
}
} // namespace
void Context::InitializeFieldGeneratorInfo(const FileDescriptor* file) {

Loading…
Cancel
Save