| """Starlark helpers for Objective-C protos.""" | 
 |  | 
 | # State constants for objc_proto_camel_case_name. | 
 | _last_was_other = 0 | 
 | _last_was_lowercase = 1 | 
 | _last_was_uppercase = 2 | 
 | _last_was_number = 3 | 
 |  | 
 | def objc_proto_camel_case_name(name): | 
 |     """A Starlark version of the ObjC generator's CamelCase name transform. | 
 |  | 
 |     This needs to track | 
 |     src/google/protobuf/compiler/objectivec/names.cc's UnderscoresToCamelCase() | 
 |  | 
 |     NOTE: This code is written to model the C++ in protoc's ObjC generator so it | 
 |     is easier to confirm that the algorithms between the implementations match. | 
 |     The customizations for starlark performance are: | 
 |     - The cascade within the loop is reordered and special cases "_" to | 
 |       optimize for google3 inputs. | 
 |     - The "last was" state is handled via integers instead of three booleans. | 
 |  | 
 |     The `first_capitalized` argument in the C++ code is left off this code and | 
 |     it acts as if the value were `True`. | 
 |  | 
 |     Args: | 
 |       name: The proto file name to convert to camel case. The extension should | 
 |         already be removed. | 
 |  | 
 |     Returns: | 
 |       The converted proto name to camel case. | 
 |     """ | 
 |     segments = [] | 
 |     current = "" | 
 |     last_was = _last_was_other | 
 |     for c in name.elems(): | 
 |         if c.islower(): | 
 |             # lowercase letter can follow a lowercase or uppercase letter. | 
 |             if last_was != _last_was_lowercase and last_was != _last_was_uppercase: | 
 |                 segments.append(current) | 
 |                 current = c.upper() | 
 |             else: | 
 |                 current += c | 
 |             last_was = _last_was_lowercase | 
 |         elif c == "_":  # more common than rest, special case it. | 
 |             last_was = _last_was_other | 
 |         elif c.isdigit(): | 
 |             if last_was != _last_was_number: | 
 |                 segments.append(current) | 
 |                 current = "" | 
 |             current += c | 
 |             last_was = _last_was_number | 
 |         elif c.isupper(): | 
 |             if last_was != _last_was_uppercase: | 
 |                 segments.append(current) | 
 |                 current = c | 
 |             else: | 
 |                 current += c.lower() | 
 |             last_was = _last_was_uppercase | 
 |         else: | 
 |             last_was = _last_was_other | 
 |     segments.append(current) | 
 |     result = "" | 
 |     for x in segments: | 
 |         if x in ("Url", "Http", "Https"): | 
 |             result += x.upper() | 
 |         else: | 
 |             result += x | 
 |     return result |