ProtoFieldPreconditionsCheckNotNull
Protobuf fields cannot be null, so this check is redundant

Severity
WARNING
Tags
LikelyError
Has Fix?
REQUIRES_HUMAN_ATTENTION

The problem

This checker looks for comparisons of protocol buffer fields with null via the com.google.common.base.Preconditions.checkNotNull method. If a proto field is not specified, its field accessor will return a non-null default value. Thus, the result of calling one of these accessors can never be null, and comparisons like these often indicate a nearby error.

If you meant to check whether an optional field has been set, you should use the hasField() method instead.

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("ProtoFieldPreconditionsCheckNotNull") to the enclosing element.


Positive examples

ProtoFieldPreconditionsCheckNotNullPositiveCases.java

/*
 * Copyright 2014 The Error Prone Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.errorprone.bugpatterns.testdata;

import com.google.common.base.Preconditions;
import com.google.errorprone.bugpatterns.proto.ProtoTest.TestFieldProtoMessage;
import com.google.errorprone.bugpatterns.proto.ProtoTest.TestProtoMessage;

/**
 * Positive examples for checking a proto message field using {@link
 * Preconditions#checkNotNull(Object)} and related methods.
 */
public class ProtoFieldPreconditionsCheckNotNullPositiveCases {
  public static void main(String[] args) {
    TestProtoMessage message = TestProtoMessage.newBuilder().build();

    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMessage());
    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMultiFieldList());

    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMessage(), new Object());
    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMultiFieldList(), new Object());

    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMessage(), "%s", new Object());
    // BUG: Diagnostic contains: check is redundant
    // remove this line
    Preconditions.checkNotNull(message.getMultiFieldList(), "%s", new Object());

    // BUG: Diagnostic contains: fieldMessage = message.getMessage();
    TestFieldProtoMessage fieldMessage = Preconditions.checkNotNull(message.getMessage());

    // BUG: Diagnostic contains: fieldMessage2 = message.getMessage()
    TestFieldProtoMessage fieldMessage2 = Preconditions.checkNotNull(message.getMessage(), "Msg");

    // BUG: Diagnostic contains: message.getMessage().toString();
    Preconditions.checkNotNull(message.getMessage()).toString();
    // BUG: Diagnostic contains: message.getMessage().toString();
    Preconditions.checkNotNull(message.getMessage(), "Message").toString();
  }
}

Negative examples

ProtoFieldPreconditionsCheckNotNullNegativeCases.java

/*
 * Copyright 2014 The Error Prone Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.errorprone.bugpatterns.testdata;

import com.google.errorprone.bugpatterns.proto.ProtoTest.TestProtoMessage;

/** Negative examples for invalid null comparison of a proto message field. */
public class ProtoFieldPreconditionsCheckNotNullNegativeCases {
  public static void main(String[] args) {
    TestProtoMessage message = TestProtoMessage.newBuilder().build();

    // This is not {@link com.google.common.base.Preconditions#checkNotNull}, so it should
    // be acceptable.
    Preconditions.checkNotNull(message.getMessage());
    Preconditions.checkNotNull(message.getMultiFieldList());
    Preconditions.checkNotNull(message.getMessage(), "Message");
    Preconditions.checkNotNull(message.getMultiFieldList(), "Message");
    Preconditions.checkNotNull(message.getMessage(), "Message %s", new Object());
    Preconditions.checkNotNull(message.getMultiFieldList(), "Message %s", new Object());

    // Checking a non-proto object should be acceptable.
    com.google.common.base.Preconditions.checkNotNull(new Object());
    com.google.common.base.Preconditions.checkNotNull(new Object(), "Message");
    com.google.common.base.Preconditions.checkNotNull(new Object(), "Message %s", new Object());
  }

  private static final class Preconditions {
    private Preconditions() {}

    static void checkNotNull(Object reference) {}

    static void checkNotNull(Object reference, Object errorMessage) {}

    static void checkNotNull(
        Object reference, String errorMessageTemplate, Object... errorMessageArgs) {}
  }
}