/*
 * Licensed to Julian Hyde under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Julian Hyde licenses this file to you 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 net.hydromatic.morel.eval;

import java.util.function.Consumer;

/** Implementation of {@link net.hydromatic.morel.eval.Code .Describer}. */
class DescriberImpl implements Describer {
  final StringBuilder buf = new StringBuilder();

  @Override public String toString() {
    return buf.toString();
  }

  @Override public Describer start(String name,
      Consumer<Detail> consumer) {
    buf.append(name);
    final DetailImpl detail = new DetailImpl();
    consumer.accept(detail);
    detail.end();
    return this;
  }

  /** Implementation of
   * {@link Detail}. */
  private class DetailImpl implements Detail {
    final int start = buf.length();

    @Override public Detail arg(String name, Object value) {
      buf.append(buf.length() == start ? "(" : ", ")
          .append(name)
          .append(name.equals("") ? "" : " ")
          .append(value);
      return this;
    }

    @Override public Detail arg(String name, Describable describable) {
      buf.append(buf.length() == start ? "(" : ", ")
          .append(name)
          .append(name.equals("") ? "" : " ");
      describable.describe(DescriberImpl.this);
      return this;
    }

    void end() {
      if (buf.length() > start) {
        buf.append(')');
      }
    }
  }
}

// End DescriberImpl.java
