1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import java.util.Collections; 34 import java.util.List; 35 36 /** 37 * Thrown when attempting to build a protocol message that is missing required 38 * fields. This is a {@code RuntimeException} because it normally represents 39 * a programming error: it happens when some code which constructs a message 40 * fails to set all the fields. {@code parseFrom()} methods <b>do not</b> 41 * throw this; they throw an {@link InvalidProtocolBufferException} if 42 * required fields are missing, because it is not a programming error to 43 * receive an incomplete message. In other words, 44 * {@code UninitializedMessageException} should never be thrown by correct 45 * code, but {@code InvalidProtocolBufferException} might be. 46 * 47 * @author kenton@google.com Kenton Varda 48 */ 49 public class UninitializedMessageException extends RuntimeException { 50 private static final long serialVersionUID = -7466929953374883507L; 51 UninitializedMessageException(final MessageLite message)52 public UninitializedMessageException(final MessageLite message) { 53 super("Message was missing required fields. (Lite runtime could not " + 54 "determine which fields were missing)."); 55 missingFields = null; 56 } 57 UninitializedMessageException(final List<String> missingFields)58 public UninitializedMessageException(final List<String> missingFields) { 59 super(buildDescription(missingFields)); 60 this.missingFields = missingFields; 61 } 62 63 private final List<String> missingFields; 64 65 /** 66 * Get a list of human-readable names of required fields missing from this 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. 70 */ getMissingFields()71 public List<String> getMissingFields() { 72 return Collections.unmodifiableList(missingFields); 73 } 74 75 /** 76 * Converts this exception to an {@link InvalidProtocolBufferException}. 77 * When a parsed message is missing required fields, this should be thrown 78 * instead of {@code UninitializedMessageException}. 79 */ asInvalidProtocolBufferException()80 public InvalidProtocolBufferException asInvalidProtocolBufferException() { 81 return new InvalidProtocolBufferException(getMessage()); 82 } 83 84 /** Construct the description string for this exception. */ buildDescription(final List<String> missingFields)85 private static String buildDescription(final List<String> missingFields) { 86 final StringBuilder description = 87 new StringBuilder("Message missing required fields: "); 88 boolean first = true; 89 for (final String field : missingFields) { 90 if (first) { 91 first = false; 92 } else { 93 description.append(", "); 94 } 95 description.append(field); 96 } 97 return description.toString(); 98 } 99 } 100