@Override
  public void generate(
      final Ds3ApiSpec spec,
      final FileUtils fileUtils,
      final Path destDir,
      final Ds3DocSpec docSpec)
      throws IOException {
    this.fileUtils = fileUtils;

    try {
      final ImmutableList<Request> allRequests = getAllRequests(spec, docSpec);
      final ImmutableList<Enum> allEnums = getAllEnums(spec);
      final ImmutableSet<String> enumNames = EnumHelper.getEnumNamesSet(allEnums);

      final ImmutableSet<String> arrayMemberTypes = getArrayMemberTypes(spec, enumNames);

      final ImmutableSet<String> embeddedTypes = getEmbeddedTypes(spec, enumNames);
      final ImmutableSet<String> responseTypes = RequestHelper.getResponseTypes(allRequests);
      final ImmutableSet<String> paginatedTypes = getPaginatedTypes(spec);

      final ImmutableList<Struct> allStructs =
          getAllStructs(
              spec, enumNames, responseTypes, embeddedTypes, arrayMemberTypes, paginatedTypes);

      generateHeader(allEnums, allStructs, allRequests);
      generateSource(allEnums, allStructs, allRequests);
      generateStaticFiles();
    } catch (final ParseException e) {
      LOG.error("Caught exception: ", e);
    }
  }
 /**
  * Find all types that are used as an array member, for generation of a parser for a list of a
  * type. Only applies to types that are wrapped in a common element.
  */
 public static ImmutableSet<String> getArrayMemberTypes(
     final Ds3ApiSpec spec, final ImmutableSet<String> enumTypes) {
   return spec.getTypes()
       .values()
       .stream()
       .flatMap(type -> type.getElements().stream())
       .filter(
           element ->
               element
                   .getType()
                   .equalsIgnoreCase("array")) // only want types that array member types
       .filter(element -> !element.getComponentType().contains("UUID")) // ignore UUID
       .filter(
           element ->
               element
                   .getDs3Annotations()
                   .stream()
                   .flatMap(anno -> anno.getDs3AnnotationElements().stream())
                   .anyMatch(
                       annoElem ->
                           annoElem
                               .getValue()
                               .equals(
                                   "SINGLE_BLOCK_FOR_ALL_ELEMENTS"))) // only want wrapped array
                                                                      // types
       .filter(
           element ->
               !enumTypes.contains(
                   EnumHelper.getDs3Type(element.getComponentType()))) // ignore enums
       .map(element -> StructHelper.getResponseTypeName(element.getComponentType()))
       .collect(GuavaCollectors.immutableSet());
 }
 public CCodeGenerator() throws TemplateModelException {
   config.setDefaultEncoding("UTF-8");
   config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
   config.setClassForTemplateLoading(CCodeGenerator.class, "/templates");
   config.setSharedVariable("cTypeHelper", C_TypeHelper.getInstance());
   config.setSharedVariable("enumHelper", EnumHelper.getInstance());
   config.setSharedVariable("requestHelper", RequestHelper.getInstance());
   config.setSharedVariable("helper", Helper.getInstance());
   config.setSharedVariable("structHelper", StructHelper.getInstance());
   config.setSharedVariable("structMemberHelper", StructMemberHelper.getInstance());
   config.setSharedVariable("parameterHelper", ParameterHelper.getInstance());
 }