31
31
package com.google.protobuf;
33
import com.google.protobuf.Descriptors.FieldDescriptor;
35
import java.util.ArrayList;
36
33
import java.util.Collections;
37
34
import java.util.List;
41
37
* Thrown when attempting to build a protocol message that is missing required
51
47
* @author kenton@google.com Kenton Varda
53
49
public class UninitializedMessageException extends RuntimeException {
54
public UninitializedMessageException(Message message) {
55
this(findMissingFields(message));
50
private static final long serialVersionUID = -7466929953374883507L;
52
public UninitializedMessageException(final MessageLite message) {
53
super("Message was missing required fields. (Lite runtime could not " +
54
"determine which fields were missing).");
58
private UninitializedMessageException(List<String> missingFields) {
58
public UninitializedMessageException(final List<String> missingFields) {
59
59
super(buildDescription(missingFields));
60
60
this.missingFields = missingFields;
66
66
* Get a list of human-readable names of required fields missing from this
67
67
* message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
68
* Returns null if the lite runtime was used, since it lacks the ability to
69
* find missing fields.
69
71
public List<String> getMissingFields() {
70
72
return Collections.unmodifiableList(missingFields);
82
84
/** Construct the description string for this exception. */
83
private static String buildDescription(List<String> missingFields) {
84
StringBuilder description =
85
private static String buildDescription(final List<String> missingFields) {
86
final StringBuilder description =
85
87
new StringBuilder("Message missing required fields: ");
86
88
boolean first = true;
87
for (String field : missingFields) {
89
for (final String field : missingFields) {
95
97
return description.toString();
99
* Populates {@code this.missingFields} with the full "path" of each
100
* missing required field in the given message.
102
private static List<String> findMissingFields(Message message) {
103
List<String> results = new ArrayList<String>();
104
findMissingFields(message, "", results);
108
/** Recursive helper implementing {@link #findMissingFields(Message)}. */
109
private static void findMissingFields(Message message, String prefix,
110
List<String> results) {
111
for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
112
if (field.isRequired() && !message.hasField(field)) {
113
results.add(prefix + field.getName());
117
for (Map.Entry<FieldDescriptor, Object> entry :
118
message.getAllFields().entrySet()) {
119
FieldDescriptor field = entry.getKey();
120
Object value = entry.getValue();
122
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
123
if (field.isRepeated()) {
125
for (Object element : (List) value) {
126
findMissingFields((Message) element,
127
subMessagePrefix(prefix, field, i++),
131
if (message.hasField(field)) {
132
findMissingFields((Message) value,
133
subMessagePrefix(prefix, field, -1),
141
private static String subMessagePrefix(String prefix,
142
FieldDescriptor field,
144
StringBuilder result = new StringBuilder(prefix);
145
if (field.isExtension()) {
147
.append(field.getFullName())
150
result.append(field.getName());
158
return result.toString();