// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreValues.java
// static Value valueOf(double n) {
//   return Value.newBuilder().setNumberValue(n).build();
// }
// 
// Path: mug/src/main/java/com/google/mu/util/stream/BiCollector.java
// @FunctionalInterface
// public interface BiCollector<K, V, R> {
//   /**
//    * Returns a {@code Collector} that will first split the input elements using {@code toKey} and
//    * {@code toValue} and subsequently collect the bisected parts through this {@code BiCollector}.
//    *
//    * @param toKey
//    *        The function to read the key from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param toValue
//    *        The function to read the value from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param <E> used to abstract away the underlying pair/entry type used by {@link BiStream}.
//    */
//   // Deliberately avoid wildcards for toKey and toValue, because we don't expect
//   // users to call this method. Instead, users will typically provide method references matching
//   // this signature.
//   // Signatures with or without wildcards should both match.
//   // In other words, this signature optimizes flexibility for implementors, not callers.
//   <E> Collector<E, ?, R> splitting(Function<E, K> toKey, Function<E, V> toValue);
// }


import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.mu.protobuf.util.MoreValues.valueOf;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.mu.util.stream.BiCollector;
import com.google.protobuf.ListValue;
import com.google.protobuf.Struct;
import com.google.protobuf.StructOrBuilder;
import com.google.protobuf.Value;
/*****************************************************************************
 * ------------------------------------------------------------------------- *
 * 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.mu.protobuf.util;




/**
 * Additional utilities to help create {@link Struct} messages.
 *
 * <p>The {@code struct(name, value)} helpers can be used to create {@code Struct} conveniently,
 * for example: {@code struct("age", 10)}.
 *
 * <p>To build {@code Struct} with more than one fields, use {@link StructBuilder}; or use
 * {@link #toStruct()} to collect from a {@code BiStream}.
 *
 * <p>If you have complex nested data structures such as {@code Multimap<String, Optional<Integer>>},
 * consider to use {@link Structor}, which translates POJO to Struct for common primitive types and
 * collection types.
 *
 * @since 5.8
 */
@CheckReturnValue
public final class MoreStructs {
  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} is null
   */
  public static Struct struct(String name, boolean value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} is null
   */
  public static Struct struct(String name, double value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, String value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, Struct value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, Value value) {
    return Struct.newBuilder().putFields(name, value).build();
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, ListValue value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a {@link Collector} that collects input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreValues.java
// static Value valueOf(double n) {
//   return Value.newBuilder().setNumberValue(n).build();
// }
// 
// Path: mug/src/main/java/com/google/mu/util/stream/BiCollector.java
// @FunctionalInterface
// public interface BiCollector<K, V, R> {
//   /**
//    * Returns a {@code Collector} that will first split the input elements using {@code toKey} and
//    * {@code toValue} and subsequently collect the bisected parts through this {@code BiCollector}.
//    *
//    * @param toKey
//    *        The function to read the key from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param toValue
//    *        The function to read the value from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param <E> used to abstract away the underlying pair/entry type used by {@link BiStream}.
//    */
//   // Deliberately avoid wildcards for toKey and toValue, because we don't expect
//   // users to call this method. Instead, users will typically provide method references matching
//   // this signature.
//   // Signatures with or without wildcards should both match.
//   // In other words, this signature optimizes flexibility for implementors, not callers.
//   <E> Collector<E, ?, R> splitting(Function<E, K> toKey, Function<E, V> toValue);
// }


// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreStructs.java
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.mu.protobuf.util.MoreValues.valueOf;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.mu.util.stream.BiCollector;
import com.google.protobuf.ListValue;
import com.google.protobuf.Struct;
import com.google.protobuf.StructOrBuilder;
import com.google.protobuf.Value;

/*****************************************************************************
 * ------------------------------------------------------------------------- *
 * 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.mu.protobuf.util;




/**
 * Additional utilities to help create {@link Struct} messages.
 *
 * <p>The {@code struct(name, value)} helpers can be used to create {@code Struct} conveniently,
 * for example: {@code struct("age", 10)}.
 *
 * <p>To build {@code Struct} with more than one fields, use {@link StructBuilder}; or use
 * {@link #toStruct()} to collect from a {@code BiStream}.
 *
 * <p>If you have complex nested data structures such as {@code Multimap<String, Optional<Integer>>},
 * consider to use {@link Structor}, which translates POJO to Struct for common primitive types and
 * collection types.
 *
 * @since 5.8
 */
@CheckReturnValue
public final class MoreStructs {
  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} is null
   */
  public static Struct struct(String name, boolean value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} is null
   */
  public static Struct struct(String name, double value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, String value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, Struct value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, Value value) {
    return Struct.newBuilder().putFields(name, value).build();
  }

  /**
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, ListValue value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a {@link Collector} that collects input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
  public static <T> Collector<T, ?, Struct> toStruct(