Skip to content

Commit e2aa06e

Browse files
[ObjC] Set up a stateless test for the WKTs.
Also wire it into the regeneration script. PiperOrigin-RevId: 508751290
1 parent 31a7fb4 commit e2aa06e

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

objectivec/BUILD.bazel

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,60 @@
11
load("@rules_cc//cc:defs.bzl", "objc_library")
22
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
3+
load("@upb//cmake:build_defs.bzl", "staleness_test")
34
load("//conformance:defs.bzl", "conformance_test")
5+
load(":defs.bzl", "objc_proto_camel_case_name")
6+
7+
# The WKTs have to be checked in to support the CocoaPods and Xcode builds. This
8+
# generule and test ensure the source are current.
9+
#
10+
# TODO: Improve the bazel build so it uses these generated headers so it is
11+
# always current, and only the builds that can't easily build protoc and
12+
# generate the files rely on the checked in ones.
13+
14+
_WELL_KNOWN_TYPES = [
15+
"any",
16+
"api",
17+
"duration",
18+
"empty",
19+
"field_mask",
20+
"source_context",
21+
"struct",
22+
"timestamp",
23+
"type",
24+
"wrappers",
25+
]
26+
27+
_OBJC_WKT_NAMES = [objc_proto_camel_case_name(x) for x in _WELL_KNOWN_TYPES]
28+
29+
_OBJC_EXTS = [
30+
".pbobjc.h",
31+
".pbobjc.m",
32+
]
33+
34+
genrule(
35+
name = "gen_wkt_sources",
36+
srcs = ["//src/google/protobuf:well_known_type_protos"],
37+
outs = ["wkt/GPB" + wkt + ext for wkt in _OBJC_WKT_NAMES for ext in _OBJC_EXTS],
38+
cmd = " && ".join([
39+
"$(execpath //:protoc) --objc_out=$(RULEDIR)/wkt --proto_path=src $(SRCS)",
40+
] + [
41+
"mv $(RULEDIR)/wkt/google/protobuf/" + wkt + ext + " $(RULEDIR)/wkt/GPB" + wkt + ext
42+
for wkt in _OBJC_WKT_NAMES
43+
for ext in _OBJC_EXTS
44+
]),
45+
exec_tools = ["//:protoc"],
46+
)
47+
48+
staleness_test(
49+
name = "well_known_types_staleness_test",
50+
outs = ["GPB" + wkt + ext for wkt in _OBJC_WKT_NAMES for ext in _OBJC_EXTS],
51+
generated_pattern = "wkt/%s",
52+
tags = ["manual"],
53+
)
54+
55+
################################################################################
56+
# Objective-C Runtime Library
57+
################################################################################
458

559
objc_library(
660
name = "objectivec",

objectivec/defs.bzl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""Starlark helpers for Objective-C protos."""
2+
3+
# State constants for objc_proto_camel_case_name.
4+
_last_was_other = 0
5+
_last_was_lowercase = 1
6+
_last_was_uppercase = 2
7+
_last_was_number = 3
8+
9+
def objc_proto_camel_case_name(name):
10+
"""A Starlark version of the ObjC generator's CamelCase name transform.
11+
12+
This needs to track
13+
src/google/protobuf/compiler/objectivec/names.cc's UnderscoresToCamelCase()
14+
15+
NOTE: This code is written to model the C++ in protoc's ObjC generator so it
16+
is easier to confirm that the algorithms between the implementations match.
17+
The customizations for starlark performance are:
18+
- The cascade within the loop is reordered and special cases "_" to
19+
optimize for google3 inputs.
20+
- The "last was" state is handled via integers instead of three booleans.
21+
22+
The `first_capitalized` argument in the C++ code is left off this code and
23+
it acts as if the value were `True`.
24+
25+
Args:
26+
name: The proto file name to convert to camel case. The extension should
27+
already be removed.
28+
29+
Returns:
30+
The converted proto name to camel case.
31+
"""
32+
segments = []
33+
current = ""
34+
last_was = _last_was_other
35+
for c in name.elems():
36+
if c.islower():
37+
# lowercase letter can follow a lowercase or uppercase letter.
38+
if last_was != _last_was_lowercase and last_was != _last_was_uppercase:
39+
segments.append(current)
40+
current = c.upper()
41+
else:
42+
current += c
43+
last_was = _last_was_lowercase
44+
elif c == "_": # more common than rest, special case it.
45+
last_was = _last_was_other
46+
elif c.isdigit():
47+
if last_was != _last_was_number:
48+
segments.append(current)
49+
current = ""
50+
current += c
51+
last_was = _last_was_number
52+
elif c.isupper():
53+
if last_was != _last_was_uppercase:
54+
segments.append(current)
55+
current = c
56+
else:
57+
current += c.lower()
58+
last_was = _last_was_uppercase
59+
else:
60+
last_was = _last_was_other
61+
segments.append(current)
62+
result = ""
63+
for x in segments:
64+
if x in ("Url", "Http", "Https"):
65+
result += x.upper()
66+
else:
67+
result += x
68+
return result

regenerate_stale_files.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ readonly BazelBin="${BAZEL:-bazel} ${BAZEL_STARTUP_FLAGS}"
1515
# Run and fix all staleness tests.
1616
${BazelBin} test src:cmake_lists_staleness_test "$@" || ./bazel-bin/src/cmake_lists_staleness_test --fix
1717
${BazelBin} test src/google/protobuf:well_known_types_staleness_test "$@" || ./bazel-bin/src/google/protobuf/well_known_types_staleness_test --fix
18+
${BazelBin} test objectivec:well_known_types_staleness_test "$@" || ./bazel-bin/objectivec/well_known_types_staleness_test --fix
1819

1920
# Generate C# code.
2021
# This doesn't currently have Bazel staleness tests, but there's an existing

0 commit comments

Comments
 (0)