code: private static Visibility getEffectiveVisibilityForNonOverriddenProperty(
        PropertyReference propRef,
        ObjectType objectType,
        @Nullable Visibility fileOverviewVisibility,
        @Nullable CodingConvention codingConvention) {
      String propertyName = propRef.getName();
      if (codingConvention != null && codingConvention.isPrivate(propertyName)) {
        return Visibility.PRIVATE;
      }
      Visibility raw = Visibility.INHERITED;
      if (objectType != null) {
        JSDocInfo jsdoc = objectType.getOwnPropertyJSDocInfo(propertyName);
        if (jsdoc != null) {
          raw = jsdoc.getVisibility();
        }
      }
      JSType type = propRef.getJSType();
      boolean createdFromGoogProvide = (type != null && type.isLiteralObject());
      // Ignore @fileoverview visibility when computing the effective visibility
      // for properties created by goog.provide.
      //
      // ProcessClosurePrimitives rewrites goog.provide()s as object literal
      // declarations, but the exact form depends on the ordering of the
      // input files. If goog.provide('a.b.c') occurs in the inputs before
      // goog.provide('a'), it is rewritten like
      //
      // var a={};a.b={}a.b.c={};
      //
      // If the file containing goog.provide('a.b.c') also declares
      // a @fileoverview visibility, it must not apply to b, as this would make
      // every a.b.* namespace effectively package-private.
      return (raw != Visibility.INHERITED || fileOverviewVisibility == null || createdFromGoogProvide)
          ? raw
          : fileOverviewVisibility;
    }
docs: Returns the effective visibility of the given non-overridden property. Non-overridden
  properties without an explicit visibility annotation receive the default visibility declared in
  the file's {@code @fileoverview} block, if one exists.
  
  <p>TODO(b/111789692): The following methods are forked from `AccessControlUtils`. Consider
  consolidating them.