<T extends PipelineOptions> T as(Class<T> iface) {
    checkNotNull(iface);
    checkArgument(iface.isInterface(), "Not an interface: %s", iface);

    T existingOption = computedProperties.interfaceToProxyCache.getInstance(iface);
    if (existingOption == null) {
      synchronized (this) {
        // double check
        existingOption = computedProperties.interfaceToProxyCache.getInstance(iface);
        if (existingOption == null) {
          Registration<T> registration =
              PipelineOptionsFactory.CACHE
                  .get()
                  .validateWellFormed(iface, computedProperties.knownInterfaces);
          List<PropertyDescriptor> propertyDescriptors = registration.getPropertyDescriptors();

          Class<T> proxyClass = registration.getProxyClass();

          existingOption =
              InstanceBuilder.ofType(proxyClass)
                  .fromClass(proxyClass)
                  .withArg(InvocationHandler.class, this)
                  .build();

          computedProperties =
              computedProperties.updated(iface, existingOption, propertyDescriptors);
        }
      }
    }
    return existingOption;
  }
@Test
  public void testDisplayDataJsonSerialization() throws IOException {
    FooOptions options = PipelineOptionsFactory.as(FooOptions.class);
    options.setFoo("bar");

    @SuppressWarnings("unchecked")
    Map<String, Object> map = MAPPER.readValue(MAPPER.writeValueAsBytes(options), Map.class);

    assertThat("main pipeline options data keyed as 'options'", map, Matchers.hasKey("options"));
    assertThat("display data keyed as 'display_data'", map, Matchers.hasKey("display_data"));

    Map<?, ?> expectedDisplayItem =
        ImmutableMap.<String, String>builder()
            .put("namespace", FooOptions.class.getName())
            .put("key", "foo")
            .put("value", "bar")
            .put("type", "STRING")
            .build();

    @SuppressWarnings("unchecked")
    List<Map<?, ?>> deserializedDisplayData = (List<Map<?, ?>>) map.get("display_data");
    assertThat(deserializedDisplayData, hasItem(expectedDisplayItem));
  }