private void mergeField(final Tokenizer tokenizer,
final ExtensionRegistry extensionRegistry,
final MessageReflection.MergeTarget target)
throws ParseException {
FieldDescriptor field = null;
final Descriptor type = target.getDescriptorForType();
ExtensionRegistry.ExtensionInfo extension = null;
if (tokenizer.tryConsume("[")) {
// An extension.
final StringBuilder name =
new StringBuilder(tokenizer.consumeIdentifier());
while (tokenizer.tryConsume(".")) {
name.append('.');
name.append(tokenizer.consumeIdentifier());
}
extension = target.findExtensionByName(
extensionRegistry, name.toString());
if (extension == null) {
if (!allowUnknownFields) {
throw tokenizer.parseExceptionPreviousToken(
"Extension \"" + name + "\" not found in the ExtensionRegistry.");
} else {
logger.warning(
"Extension \"" + name + "\" not found in the ExtensionRegistry.");
}
} else {
if (extension.descriptor.getContainingType() != type) {
throw tokenizer.parseExceptionPreviousToken(
"Extension \"" + name + "\" does not extend message type \"" +
type.getFullName() + "\".");
}
field = extension.descriptor;
}
tokenizer.consume("]");
} else {
final String name = tokenizer.consumeIdentifier();
field = type.findFieldByName(name);
// Group names are expected to be capitalized as they appear in the
// .proto file, which actually matches their type names, not their field
// names.
if (field == null) {
// Explicitly specify US locale so that this code does not break when
// executing in Turkey.
final String lowerName = name.toLowerCase(Locale.US);
field = type.findFieldByName(lowerName);
// If the case-insensitive match worked but the field is NOT a group,
if (field != null && field.getType() != FieldDescriptor.Type.GROUP) {
field = null;
}
}
// Again, special-case group names as described above.
if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
!field.getMessageType().getName().equals(name)) {
field = null;
}
if (field == null) {
if (!allowUnknownFields) {
throw tokenizer.parseExceptionPreviousToken(
"Message type \"" + type.getFullName() +
"\" has no field named \"" + name + "\".");
} else {
logger.warning(
"Message type \"" + type.getFullName() +
"\" has no field named \"" + name + "\".");
}
}
}